What async promised and what it delivered

· Source ↗

TLDR

  • The async/await saga is a chapter-by-chapter story: callbacks introduced hell, promises introduced boilerplate, await cleaned the syntax but left function coloring and performance tradeoffs unresolved.

Key Takeaways

  • Each generation of async solved its predecessor’s most visible pain while introducing subtler costs at the next layer.
  • Function coloring – the forced split between async and sync call graphs – is the central structural cost async/await imposes on a codebase.
  • The piece frames async/await as a design pattern with real tradeoffs, not a universal concurrency solution, and traces how different ecosystems responded.
  • Go’s CSP model and Rust’s zero-cost state machines represent divergent answers to the same underlying concurrency problem async/await was solving.

Hacker News Comment Review

  • Commenters challenged the article’s thread-cost framing: Linux thread creation benchmarks closer to 10 microseconds, not milliseconds, weakening the core argument for preferring async over OS threads in most applications.
  • The discussion landed on a sharp language-by-language split: JS had no choice given its single-threaded runtime; C# async composes with cancellation tokens and a real thread pool; Rust async compiles to call-site state machines with zero runtime overhead – treating them as one pattern misrepresents all three.
  • Function coloring drew more nuance than the article implies: recoloring during refactors is low friction, but async on hot paths adds real latency via accumulated promise microtasks, making it a performance concern rather than just a maintenance one.

Notable Comments

  • @dcan: argues embedded Rust async is the genuinely compelling case – Embassy and RTIC make hardware abstractions like DMA-backed UART practical where OS threads aren’t available.
  • @SebastianKra: points out that async/await’s value in JS is partly about synchronous code clarity – the absence of await is an implicit signal that nothing will interleave with your computation, acting as a lightweight type-system contract.

Original | Discuss on HN