Get AI summaries of any video or article — Sign up free
I Spent 18 Months Using Rust And Regret It thumbnail

I Spent 18 Months Using Rust And Regret It

The PrimeTime·
5 min read

Based on The PrimeTime's video on YouTube. If you like this content, support the original creators by watching, liking and subscribing to their content.

TL;DR

Rust’s biggest practical pain point is not speed; it’s the complexity that emerges when async, lifetimes, and generics combine in real systems.

Briefing

Rust’s promise—speed without garbage collection—collides hard with the realities of building complex, async-heavy systems. After 18 months rebuilding an algorithmic trading platform in Rust, the narrator lands on a blunt verdict: the language is “great” in narrow areas, but the overall experience becomes so verbose and unintuitive—especially once async, lifetimes, and generics stack together—that development turns into a long cycle of refactoring and frustration.

The performance pitch for Rust starts with a familiar hierarchy: languages that manage memory at runtime (reference counting, shared ownership patterns, garbage collection) tend to lose ground at the top end. Rust is often marketed as a fastest-and-safest option, but the trade-off shows up in practice. The narrator points out that Rust’s “safety” isn’t free: to keep things correct, the language pushes developers into patterns like Arc/Mutex and cloning, and once async enters the picture, the code can become extremely hard to reason about. The most painful moments aren’t basic Rust—they’re the “Ayn land” parts where lifetimes and trait bounds interact with futures across boundaries.

That complexity shows up in concrete coding pain: writing helper abstractions for retry logic over async operations can fail to compile, forcing the developer to abandon helper functions entirely. Even when the core logic is straightforward—start a session, await operations, open a transaction, handle errors with match, and cap retries—the surrounding type machinery can become the bottleneck. The narrator describes a “non-differentiable” learning curve: borrow checking is steep, lifetimes add another steep wall, and async makes everything “go off the table.” The result is a “pit of success” that feels shallow: Rust makes it easy to do the wrong thing quickly (for example, by leaning on the question-mark operator to propagate errors without enough context), so developers may end up debugging behavior they didn’t fully understand.

Error handling becomes a second flashpoint. Rust’s ergonomics—especially the convenience of propagating errors—can hide where failures originate, leading to “oopsy dazing” and vague blame. The narrator contrasts this with Go’s more explicit error handling, which forces context wrapping and makes it clearer where things go wrong. Rust can still be strong here—if developers avoid unsafe unwraps and use better error construction—but the learning curve means many people don’t reach that level quickly.

Despite the regret, the narrator isn’t anti-Rust across the board. Command-line work, file transforms, and certain structured patterns read well. Multi-threading is also described as enjoyable when using Arc/Mutex. Still, for maximum performance in async systems, the narrator concludes Rust is less practical than alternatives like Go or Zig, and the Rust community’s culture can feel overly cult-like or hostile when flaws are raised. The final takeaway is less about Rust being “bad” and more about fit: Rust demands deep mastery before it pays off, and skipping that preparation can turn a promising tool into a long, expensive refactoring loop—one that matters when milliseconds count in trading systems.

Cornell Notes

After 18 months rebuilding an algorithmic trading platform in Rust, the narrator regrets the choice because Rust’s safety and performance come with steep complexity costs. The hardest parts arrive when async, lifetimes, and generics combine, turning otherwise simple retry/transaction logic into verbose, hard-to-compile code and forcing abandonment of helper abstractions. Error handling is another friction point: the question-mark operator can make error propagation too convenient, sometimes obscuring where failures originate. Rust shines in narrower domains—command-line tasks, file transforms, and some multi-threading patterns—but the overall learning curve and “pit of success” feel too shallow for many teams. The practical lesson: Rust can be excellent, yet it requires deep preparation to avoid a cycle of refactoring and debugging.

Why does the narrator believe Rust’s “fast and safe” reputation breaks down in real async systems?

The core issue is not raw speed; it’s the developer cost of maintaining correctness. Once async enters, lifetimes and trait bounds interact across future boundaries, producing code that is difficult to write and difficult to compile. The narrator describes this as a sharp learning-curve jump: borrow checking is steep, lifetimes add another steep wall, and async makes the combined system feel nearly unmanageable without strong internal Rust knowledge.

What specific coding pain illustrates the cost of Rust’s type system in the trading rewrite?

Retry and transaction logic becomes the stress test. The narrator says they eventually abandoned helper functions because the code “literally couldn’t get…to compile,” especially when trying to generalize retry over async operations. Even when the control flow is clear—start a session, await, begin a transaction, run an operation, match errors, and cap retries—the surrounding generics/lifetimes/async constraints can dominate the work.

How does the narrator critique Rust error handling, despite acknowledging Rust’s strengths?

The critique targets ergonomics. The question-mark operator makes it easy to propagate errors quickly, which can lead to insufficient context about where the failure happened—creating a “pit of success” problem that encourages shallow handling. The narrator contrasts this with Go-style explicit error handling, where developers often wrap errors with context at each layer, making root causes easier to locate.

What does the narrator say Rust does well, and where does it feel most usable?

Rust feels strongest in simpler, more structured tasks: command-line operations, file reads and transforms, and certain multi-threading patterns. The narrator also likes Rust’s approach to errors as values and describes multi-threading as generally enjoyable when using Arc/Mutex (and sometimes cloning) to manage shared state.

What broader lesson does the narrator draw about adopting Rust for performance-critical work?

Rust can be worth it, but only after substantial mastery. The narrator recommends spending time learning allocations, reading the async material, and practicing with projects before rewriting production systems. Skipping that preparation can trap teams in repeated refactoring because it’s hard to get the “right” design on the first attempt—especially in async-heavy code.

Review Questions

  1. Which Rust features (as described here) most intensify complexity when building async trading systems, and why?
  2. How does the question-mark operator contribute to the narrator’s “pit of success” concern in error handling?
  3. What kinds of tasks does the narrator say Rust handles especially well, and how does that contrast with async transaction/retry code?

Key Points

  1. 1

    Rust’s biggest practical pain point is not speed; it’s the complexity that emerges when async, lifetimes, and generics combine in real systems.

  2. 2

    Helper abstractions for async retry/transaction logic can become extremely hard to compile, sometimes forcing developers to abandon them.

  3. 3

    The question-mark operator can make error propagation too convenient, potentially obscuring where failures originate unless developers add context deliberately.

  4. 4

    Rust can feel excellent for command-line work and data transforms, and multi-threading can be manageable with Arc/Mutex patterns.

  5. 5

    The narrator’s learning-curve model is stepwise: borrow checking, then lifetimes, then async—after which the combined system becomes especially difficult.

  6. 6

    For performance-critical trading, the development-time cost of complexity may outweigh the runtime benefits if the team isn’t prepared to master Rust deeply.

  7. 7

    Community dynamics can amplify frustration: harsh or hostile feedback can discourage honest discussion of Rust’s real-world drawbacks.

Highlights

The narrator’s core regret is that async-heavy Rust turns straightforward trading logic into a compile-and-refactor grind, especially when lifetimes and generics collide.
Error propagation via the question-mark operator can hide root causes by making it too easy to “just propagate” without adding context.
Rust feels most rewarding in bounded domains like command-line tooling and file transforms, while async transaction/retry code is where it breaks down.
The “pit of success” problem: Rust makes some wrong approaches easy, so teams may repeatedly rebuild until they internalize the language’s deeper patterns.

Topics

Mentioned

  • Austin Starks
  • Adam Elmore
  • Aaron Francis
  • RC
  • Arc
  • Mutex
  • AI
  • CMU
  • HDMI