Summary of "I Spent 18 Months Using Rust And Regret It"
Overview
The speaker recounts rebuilding an algorithmic trading platform in Rust over ~18 months and expresses regret. Rust has real strengths (speed, safety, good enums/typing, multithreading), but also major practical downsides for this kind of project. Much of the piece is a technical critique (syntax, semantics, async, lifetimes, error handling) balanced with some praise.
Key technical criticisms and pitfalls
-
Performance is nuanced Rust can be fast, but common idioms such as
Arc,Mutex,Rc, and frequentcloneor other managed/shared-memory patterns can significantly reduce performance. The fastest code often comes from manual-memory languages when you avoid managed/shared abstractions. -
Verbose and unintuitive advanced syntax Once you hit advanced Rust features (lifetimes + async + traits + generics), syntax and types get very complex. Examples include pinned boxes, async/await types, and signatures such as:
F: Fn(...) -> impl Future + Send + 'static -
Borrow checker, lifetimes, and async form a steep learning curve These features combine into a fragmented, steep learning curve; mistakes frequently produce inscrutable compiler errors or long compile-time debugging sessions.
-
Generics and abstraction can hurt compile/maintainability Generic helper functions and deep abstraction may become impossible to compile or maintain; sometimes pragmatic code duplication is the only workable solution.
-
Error handling encourages shallow propagation The convenient
?operator often leads to propagating errors up many stack frames without context, making runtime debugging difficult (poor stack traces/context unless you deliberately add them). This is framed as a“shallow pit of success” — easy to do the wrong thing.
-
Tooling dependency and required expertise Without very strong Rust knowledge or advanced LLM help, writing and understanding complex async/generic code is hard.
-
Community behavior can be unhelpful Some community interactions (e.g., on forums or subreddits) were described as dismissive or hostile; replies sometimes reduce critiques to “skill issue” instead of acknowledging trade-offs.
-
Ecosystem-specific pain points Examples included difficulty with specific crates (e.g., MongoDB Rust crate) and community advice that simply suggested switching databases rather than addressing the underlying interoperability/usability concern.
Positive aspects and when Rust works well
-
Excellent fit for certain tasks CLI tools, file transformations, and single-threaded workloads with predictable allocations are natural Rust strengths.
-
Strong type system and enums Enums,
impl From/TryFrom, and a powerful type system help model problems precisely. -
Safe concurrency No null pointers, error-as-values, channels, and
Option/Resulttypes can reduce many concurrency pitfalls. Multi-threaded programming can be enjoyable because Rust enforces safety constraints that help avoid whole classes of bugs. -
Potential for high performance When written carefully and avoiding managed/shared patterns, Rust can be very fast.
Comparisons to other languages and alternatives
-
TypeScript/JavaScript Rust is safer and faster, but the ergonomics and developer cost of Rust can make it less appealing if developer speed is a priority.
-
Go Praised for simplicity and developer ergonomics: explicit error handling, readability, and faster iteration make Go a good middle-ground if development speed matters more than squeezing maximum performance.
-
Zig Suggested as a better balance of control and safety for many cases; the speaker preferred Zig over Rust in some scenarios.
-
OCaml / Jane Street / FPGAs For true HFT or nanosecond-sensitive systems, specialized platforms (e.g., OCaml at Jane Street or FPGA solutions) are where the highest performance/lowest latency is achieved — Rust or Go may not be ideal for extreme latency demands.
-
C++ Rust is safer than C++ for memory safety, but C++ can match performance when memory is expertly managed; each has trade-offs.
Practical recommendations / workflow advice
-
Don’t rewrite large systems into Rust lightly. If you consider Rust for production, spend months learning: read The Rust Book and the Async Book, and practice allocations, pin/pin-project patterns, async/lifetimes/traits together.
-
Weigh developer productivity vs. latency gains. A few dozen milliseconds of extra latency (e.g., in Go) might be acceptable if development speed and maintainability are substantially better.
-
Improve error context deliberately. Use
anyhow, custom error types, or roll-your-own error wrapping; avoid blind use of?everywhere and prefer explicit error wrapping to preserve traceability. -
Accept pragmatic duplication when abstraction complicates compilation. Structure generics carefully — placement of bounds matters — and be willing to duplicate code rather than fight the compiler.
-
Explore other languages/tools where appropriate. Consider Zig, Go, OCaml, or platform-specific solutions (FPGAs) depending on the problem domain.
-
Practice for months before large rewrites. A suggested rule of thumb: spend ~6 months practicing Rust features before committing to a full rewrite.
Resources / guides / tutorials mentioned
- The Rust Book and the Async Book (recommended prerequisites before major rewrites)
- Topics to study:
pin,pin-project, and allocation awareness - Error handling tools:
anyhow, custom error wrapping approaches - Talks: TigerBeetle database talk/presenter highlighted as illuminating
- Practical advice: spend substantial hands-on time learning async, lifetimes, and traits together
Main speakers / sources referenced
- Austin Starks — original article / author referenced
- The Primagen — the YouTuber/commentator presenting this summary/critique
- Rust community (subreddit and commenters) — multiple reactions and advice quoted
- Named individuals mentioned: Adam Elmore, Aaron Francis (noted as friendly), and “Joran” (TigerBeetle presenter). A few others were referenced imprecisely.
Bottom line
Rust offers strong safety guarantees and the potential for high performance, but its advanced features (lifetimes, async, generics, error propagation) impose significant cognitive and development costs. For latency-sensitive trading, Rust can be appropriate — but only if your team is prepared for the steep learning curve and ongoing tooling/maintenance trade-offs. Otherwise, languages like Go or Zig (or platform-specific solutions such as OCaml/FPGA) may be more pragmatic.
Category
Technology
Share this summary
Is the summary off?
If you think the summary is inaccurate, you can reprocess it with the latest model.