Analysis

Async Rust still has binary bloat, seven years after stabilization

Async Rust's biggest promise still leaks bytes. A new critique says the compiler, not developers, has left state-machine overhead in place.

Nina Kowalski··5 min read
Published
Listen to this article0:00 min
Share this article:
Async Rust still has binary bloat, seven years after stabilization
Source: byteiota.com

Why the "still MVP" critique hits a nerve

Async Rust was supposed to make back-end concurrency feel clean, fast, and cheap. Instead, Tweede golf’s May 3, 2026 analysis, “Async Rust never left the MVP state,” argues that the feature still carries the feel of a rough first release, even nearly seven years after stabilization. That timing matters because Rust’s Future trait stabilized in Rust 1.36.0 on July 4, 2019, and async/await followed in Rust 1.39.0 on November 7, 2019. The critique is not that async Rust failed to arrive, but that it arrived without fully delivering the zero-cost story people were promised.

The sting of that argument is bigger than one opinion post because async Rust sits near the center of how modern Rust teams build network services, runtimes, and storage systems. If the abstraction still leaves visible cost behind, then the issue is no longer just elegance. It becomes a question of whether Rust’s concurrency model is truly paying its own way in production.

Where the binary bloat shows up

The sharpest complaint in the piece is binary size. The author says async state machines can add roughly 2% to 5% to binary size, because the compiler generates machinery that it does not always optimize away well enough. That is not a niche annoyance on constrained targets. Rust’s embedded documentation warns that unoptimized binaries can occupy dozens of KiB of Flash, and that the resulting image may not fit on the target device at all.

That puts a concrete number on the pain. A 2% to 5% increase can look harmless in a desktop service, but on firmware and storage-constrained systems it can be the difference between shipping an image and squeezing features out to make room. The larger point is that async code does not only affect runtime behavior. It can also inflate the artifact itself, which makes the cost visible long before the first request is served.

The real complaint is about codegen, not async itself

What makes the piece unusually sharp is that it does not treat this as an indictment of async Rust as a design. Instead, it frames the problem as a compiler and code generation opportunity. That is a crucial distinction, because it shifts the discussion from “should Rust have async?” to “why is the implementation still leaving so much performance on the table?”

The article lays out several specific optimization ideas:

  • Replace some post-completion panics with `Poll::Pending` in release builds
  • Remove state machines for async blocks that never actually await
  • Inline futures that have only a single await point
  • Collapse identical states created by match arms with multiple awaits

Those are the kinds of details that matter to people shipping real code. They point to wasted branches, duplicate state, and generated scaffolding that survives after the compiler has done its best work. In other words, the frustration is not with async syntax itself. It is with the amount of structure that still leaks through into the final binary.

Why the ecosystem should treat this as a health check

The broader significance is that Rust is not standing still here. The Rust Project said in its December 2025 update that it was working toward 41 project goals, with 13 of them designated as flagship goals. That is a crowded roadmap, which makes any request for deeper compiler work a real tradeoff, not an abstract wish list item. Still, async has remained important enough that the project has kept pushing on it.

The Rust Async Working Group has described its goal as bringing the async experience closer to parity with sync Rust, and recent releases show that the work is ongoing. Rust 1.75, announced in December 2023, included support for async fn in traits and return-position impl Trait in traits. Rust 1.85.0 then shipped async closures on February 20, 2025. Those are meaningful steps, but the new critique argues that feature growth is not the same thing as implementation maturity.

Why the post matters beyond commentary

The piece becomes more than analysis because the author says they have submitted a Rust Project Goal and are looking for help funding the work, with the aim of fixing the inefficiencies in the compiler itself. That turns the post into a bid for ecosystem attention, not just a complaint about rough edges. It also makes the binary bloat argument harder to dismiss, because it comes attached to a plan for root-cause improvement.

That framing matters for back-end teams, but it matters even more for embedded and size-sensitive work. Rust’s reputation has always rested on the promise that safety does not have to mean bloat. If async Rust still needs extra mass to do everyday work, then the language has a concrete optimization target, not a philosophical problem.

What this means for teams using async Rust now

The takeaway is not to avoid async Rust. It is to treat async code as something that still deserves scrutiny at the binary level, especially when targets are constrained or deployment size matters. The state machines are real, the generated code is real, and the overhead can show up in ways that change what fits on a device.

This is what makes the critique feel consequential. Seven years after stabilization, async Rust is no longer in question as a feature. What is in question is whether the implementation has caught up with the promise, or whether the ecosystem still has to keep paying a hidden tax for every future it builds.

Know something we missed? Have a correction or additional information?

Submit a Tip

Never miss a story.

Get Rust Programming updates weekly. The top stories delivered to your inbox.

Free forever · Unsubscribe anytime

Discussion

More Rust Programming News