Principles for Fast Tokio Applications

(dial9-rs.github.io)

77 points | by carllerche 3 hours ago ago

15 comments

  • dist1ll 18 minutes ago ago

    When you're at a point of tuning Tokio, consider taking a look at ef_vi/DPDK + SPDK

  • Tsarp 3 hours ago ago

    One great use of agentic coding is being able to add and very granular tracing instrumentation to help with these sort of optimizations.

    • jeffbee 3 hours ago ago

      Also a great way to make sure that your app spends most of its time in observability overhead. For example even the latency histogram that the OP mentions is wildly expensive.

      • Veserv 2 hours ago ago

        That just sounds like bad tracing implementations. A good tracing implementation should be able to drive gigabytes per second of trace logs to memory. If you are generating it slow enough to allow actual offload then you should be in the 1—10% range even if you are saturating your offload.

        You should, of course, upper bound this overhead by switching to a full time travel debugging solution, thus tracing everything, when you get to the 10-30% range.

        The only way you get to “majority” is if your trace implementation is slower than time travel debugging and provides less information, but then why choose something worse in every dimension.

        • jeffbee 34 minutes ago ago

          I'm just reporting from the trenches here. I think you are suggesting that everyone is aware of and capable of using state-of-the-art (from 20 years ago) tracing schemes like XRay[1], when in reality they are not. Most projects would be well-served by any basic profiler but even profiling is apparently for wizards, because I've seen a lot of projects that will resort to manually annotating functions with OTel trace spans, which are ~millions of times more expensive than function calls. Even eBPF uprobe/uretprobe is 100x more expensive than XRay, at a minimum. HotSpot's JFR is like a miracle compared to what people suffer through to diagnose Rust+Tokio.

          1: https://llvm.org/docs/XRay.html ... is there even a Rust analog to this?

          • duped 10 minutes ago ago

            Not even an analog: https://doc.rust-lang.org/beta/unstable-book/compiler-flags/...

            It's worth pointing out though that just tracing function calls isn't good enough for the kinds of stackless coroutines that run in async Rust tasks. You need a way of mapping between the async tasks and the compiler emitted traces.

            afaik, C/C++ have the same problem.

      • nicoburns 2 hours ago ago

        One legitimately great thing about LLMs is that it makes it feasible to add these kind of tracing instrumentations temporarily for profiling and then throw them away so they never reach source control let alone production.

        • jeffbee 2 hours ago ago

          I can get an LLM to trace my incomprehensible Tokio application which was also written by an LLM, which is why I don't understand its behavior. Truly the future we were promised.

      • foota an hour ago ago

        Just curious, why? Is this true even if you did something like a per-CPU histogram that uses atomic ops to increment?

      • MomsAVoxell 3 hours ago ago

        If you’re not using eBPF to trace your app you’re doing it wrong.

        • jeffbee 3 hours ago ago

          The low cost of eBPF tracing is another myth.

          • MomsAVoxell an hour ago ago

            1) Its no myth, but you can definitely foot-bullet into doing it wrong, and 2) it's a far better path to take than in-app telemetry.

  • jeffbee 3 hours ago ago

    All of the significant server applications I have encountered in the industry have suffered from the same problem, which surprised their authors but seemed obvious to me: the application was spending the majority of its CPU time doing meta-work like entering and leaving epoll, stealing work from itself, etc. There are principles for writing Tokio servers and these are good points in the OP but I think they are little-known and too easy to violate.

    • cube00 3 hours ago ago

      I can't say I'm surprised when I see the 100+ function stack traces that Axum built on Tokio produces.

      Before you say Axum is "holding it wrong" the project lives under the tokio-rs GitHub org.

      • rusbus an hour ago ago

        Note that most of those end up getting inlined in practice