Should You Rewrite It in Rust? A Decision Framework for 2026

Max WellsMax WellsFounder of Rustify

The honest answer to 'should we rewrite this in Rust?' : a practical decision framework with real case studies from Discord, npm, Cloudflare, and a ROI calculation.

By Rustify Team, updated march 2026

TL;DR: "Rewrite it in Rust" is sometimes the right answer and sometimes expensive overengineering. The decision comes down to four factors: performance requirements, memory safety criticality, team capacity, and maintenance burden of the existing system.

  • Rewrite wins when: the system is performance-critical, unsafe, or has unbounded memory issues
  • Rewrite loses when: the system works fine, the team is small, or you need to ship fast
  • Partial rewrites (hot paths only) often outperform full rewrites on ROI
  • Real numbers: Discord cut p99 latency from 95ms → 5ms; npm cut CPU 50%; Cloudflare cut memory 70%
  • The honest cost: a full rewrite takes 2–5x longer than estimated, always

Who Should Read This?

This article is written for senior engineers, engineering managers, and technical leads who are evaluating whether a Rust rewrite makes sense for a specific service or system. You likely have 5–10 years of experience in Python, Go, Java, or C++, and you have been asked by leadership : or are asking yourself : whether Rust is the answer to a performance or reliability problem. Rust engineers in the United States at this seniority level earn $185K–$230K annually, and the decision to invest in a Rust migration often touches team hiring, budgeting, and multi-quarter planning. This article gives you the vocabulary and framework to make that decision confidently, backed by real case studies and honest ROI math.


What Is "RIIR" and Why Does the Phrase Exist?

"Rewrite It in Rust" (RIIR) started as a joke about Rust evangelism but evolved into a genuine engineering discussion : because in some domains, Rust rewrites deliver order-of-magnitude improvements.

The joke is familiar to anyone in the systems programming community: whatever the problem, the Rust community's answer is "rewrite it in Rust." Like all good jokes, it has a kernel of truth.

Discord's 2020 blog post documenting their Go → Rust rewrite is often cited as the canonical case. Their Read States service had p99 latency spikes of 95ms in Go due to garbage collection pauses. The Rust rewrite brought p99 to 5ms : and the memory usage dropped from 70 GB to 9 GB. Not a 10% improvement. A 17x reduction in latency and an 8x reduction in memory.

But Discord's result depends entirely on their specific situation: a latency-sensitive, memory-heavy, long-running service where Go's GC pauses were the root cause. Not every service is Discord's Read States.

The RIIR meme also reflects a real frustration: systems written in C or C++ that accumulate CVEs, systems written in Python or Ruby that hit performance walls, and services written in Go that suffer from GC-induced latency spikes. For all of these, "rewrite in Rust" is at minimum a coherent proposal : whether it's the right one depends on a structured analysis.

Understanding the RIIR decision framework means understanding when it applies and when it doesn't. Teams that answer this question rigorously save months of misallocated engineering effort. Teams that answer it reflexively : in either direction : often regret it.


What Are the Four Questions That Determine Whether to Rewrite?

Before considering a rewrite, answer four questions: Is performance the real bottleneck? Is memory safety actively causing incidents? Does the team have Rust capacity? Is the existing codebase worth throwing away?

Question 1: Is performance actually the bottleneck?

Most software is not performance-bound. A CRUD API waiting on database I/O spends 95% of its time on network and disk : the language runtime contributes less than 1% of total latency. Rewriting that in Rust will not meaningfully improve user experience.

Performance rewrites make sense when:

  • CPU usage is consistently high and profiling shows the application code (not I/O) is the bottleneck
  • GC pauses are causing latency spikes in a latency-sensitive service (e.g., gaming, trading, real-time ML inference)
  • Memory footprint is growing unboundedly (memory leak, per-connection overhead)
  • Throughput has hit a hard ceiling that horizontal scaling cannot solve cost-effectively

Question 2: Is memory safety causing real problems?

If your service is written in C or C++ and you have a history of memory safety CVEs (use-after-free, buffer overflow, heap corruption), a Rust rewrite is a security investment, not just a performance investment. The NSA, CISA, and the White House's ONCD have explicitly recommended moving to memory-safe languages : for good reason: ~70% of Microsoft's CVEs and ~65% of Chrome's are memory safety issues.

For Python, JavaScript, or Java services, memory safety is less of a concern : the runtime handles it. The rewrite case there is almost purely about performance.

Question 3: Does the team have Rust capacity?

A Rust rewrite by a team that doesn't know Rust is a recipe for a multi-year project that ships never. Rust's learning curve is 3–6 months to productive : a full team ramp-up takes longer. Either hire experienced Rust engineers, train the team first (bootcamp or structured learning), or scope the rewrite to a subteam that's already proficient.

Question 4: Is the existing codebase worth throwing away?

Years of accumulated business logic, edge case handling, and bug fixes live in your existing codebase. A rewrite throws all of that away and requires you to rediscover every edge case in production. Joel Spolsky called this "the single worst strategic mistake any software company can make" : and he's right in cases where the logic is complex and the bugs are subtle.

Rewrites are more defensible when: the existing codebase is genuinely unmaintainable (not just ugly), the business logic is well-tested and can be ported with confidence, or the system is a thin layer without deep business logic (a proxy, a data pipeline, a runtime).


3 spots open this month → Check if you are eligible.

We help experienced developers transition into Rust roles at €80K–€150K+ in Europe or $130K–$200K+ in the US.

What Do the Real Case Studies Show About Rewrite ROI?

Successful Rust rewrites at Discord, npm, Cloudflare, and AWS each shared the same profile: a performance-critical service with measurable bottlenecks, done by teams that already knew Rust.

Discord: Go → Rust (Read States service, 2020)

The problem: GC pauses in Go caused latency spikes every 2 minutes : visible to users as Discord "hiccups."

The result:

MetricGoRustImprovement
p99 latency95ms5ms19x faster
Memory usage70 GB9 GB8x smaller
GC pausesVisible, every ~2 minNoneEliminated

Why it worked: The service had no business logic to port. It was a stateful cache : a pure systems layer where Go's GC was the documented root cause. The rewrite was focused, the team was prepared, and the bottleneck was real.

npm: Node.js → Rust (auth service, 2019)

The problem: npm's auth service was CPU-bound under peak load : Black Friday package installs pushed Node.js to its limits.

The result: 50% CPU reduction at peak load, with the same hardware. More importantly, they reduced the p99 latency under load from seconds to milliseconds.

Why it worked: Auth is stateless and computationally intensive (bcrypt, JWT validation): exactly the workload where Rust's lack of runtime overhead shows up in benchmarks.

Cloudflare: NGINX Lua → Rust (Pingora, 2022)

The problem: NGINX's architecture didn't support the connection reuse patterns Cloudflare needed. Memory consumption at scale was significant.

The result: 70% memory reduction, CPU cut in half versus the previous system. Pingora now handles trillions of requests per day.

Why it worked: Cloudflare is not a typical company : they process more internet traffic than almost anyone. At that scale, a 2x CPU improvement translates directly to billions of dollars in infrastructure costs. The ROI calculation is trivially positive.

AWS: C → Rust (Firecracker, 2018)

The problem: Lambda needed a hypervisor that was both fast and provably memory-safe : C VMMs have a long history of CVEs.

The result: Firecracker boots microVMs in <125ms, uses <5 MB of memory per VM, and has shipped with zero memory safety CVEs since launch. It powers AWS Lambda and AWS Fargate at scale.

Why it worked: Safety was the primary requirement, not just performance. Rust was chosen because it's the only language that can provide memory safety guarantees at the systems level without a GC.


When Does a Rewrite Not Make Sense?

Most services are not performance-bound, most teams don't have Rust capacity, and most rewrites take longer and cost more than estimated : making "no" the right default answer.

Don't rewrite when:

  • The service is I/O bound: Database queries, third-party API calls, and network latency dominate response time. Rust will not make a database query faster.
  • The team doesn't know Rust yet: A rewrite by a team learning Rust in production is a high-risk bet. Learn Rust first, then evaluate the rewrite.
  • The business logic is complex and poorly tested: You will reintroduce every bug that the existing code has fixed over years.
  • You just want "better code": Refactoring the existing codebase in its current language is usually faster and safer.
  • Startup or rapid iteration phase: Rust's compile times and learning curve slow iteration speed. Use fast-iteration languages early, then optimize later with data.
  • The bottleneck is in a library you don't control: If your Python service spends 80% of its time in NumPy (compiled C), switching to Rust won't help: NumPy's hot paths are already native.

The clearest sign of a misguided rewrite: "we want to use Rust" is the primary motivation, with performance or safety as a post-hoc justification. Technical decisions should be justified by business outcomes : not by enthusiasm for a technology, however well-earned that enthusiasm may be.

A useful forcing function: require that any rewrite proposal include a production profiling report showing the confirmed bottleneck, a break-even timeline calculation, and a team Rust readiness assessment. If the proposal cannot produce these three documents, it is not ready to be approved.


What Is the Partial Rewrite Strategy and When Does It Outperform a Full Rewrite?

A partial rewrite : replacing only the hot paths with Rust via FFI or as microservices : often achieves 80% of the performance benefit at 20% of the cost.

The strangler fig pattern applied to Rust:

  1. Identify the bottleneck with profiling : not guessing. Use py-spy, perf, or your platform's profiler to find the actual hot code.
  2. Extract the hot path into a standalone Rust library or service.
  3. Call from the existing system via FFI (Python → Rust via PyO3, Node.js → Rust via Neon), via gRPC, or via a sidecar process.
  4. Measure the improvement against your actual bottleneck.
  5. Expand scope only if the improvement is significant and the integration cost is justified.

Real example: A Python data processing pipeline spending 70% of CPU time on a custom text tokenizer. Rewriting just the tokenizer in Rust via PyO3 brought total pipeline throughput up 4x : in one week, by one engineer, with no changes to the surrounding Python code.

Replacing the entire pipeline in Rust might have achieved a 5x improvement : but would have taken 3 months, required porting the entire orchestration logic, and introduced operational risk. The partial rewrite delivered 80% of the value at 6% of the cost.

This pattern scales: a Java service with a hot cryptographic verification path, a Go service with a CPU-intensive parsing loop, a Node.js service with a compression bottleneck : in each case, a Rust extension to the hot path costs one or two engineer-weeks and captures most of the performance gain. The remaining service stays in its original language, benefiting from the existing team's expertise and the existing deployment infrastructure.


How Do You Calculate the ROI of a Rust Rewrite?

ROI = (infrastructure savings + incident cost reduction + performance value) ÷ (engineer cost + maintenance cost).

A practical framework: calculate infrastructure savings (current monthly cloud cost × expected reduction of 20–70%, annualized), incident reduction (CVE remediation costs if rewriting for safety, or customer churn cost from latency if rewriting for performance), and engineer cost (Rust ramp-up of 3–6 months per engineer, rewrite time × 2.5 since rewrites always take longer, plus opportunity cost). Break-even is total engineer cost divided by monthly savings.

Red flags in the calculation:

  • Break-even > 18 months: reconsider
  • Performance bottleneck is unconfirmed by profiling: do not proceed
  • Team Rust experience is zero: add 6 months to the timeline

When Rust engineers cost $185K–$230K annually in the US market, a three-engineer rewrite team over six months represents $275K–$345K in direct engineering cost : before opportunity cost. That cost requires a substantial and documented benefit to justify. Cloud spend reductions of $50K/year would break even in approximately six years; reductions of $200K/year break even in under two years. The math forces clarity.


What Common Mistakes Do Teams Make When Evaluating a Rust Rewrite?

Teams most often fail by skipping the profiling step, underestimating the timeline, or treating Rust learning as a side task rather than a prerequisite.

  • Starting without confirmed profiling data. "We think the service is slow because of the language" is not a sufficient basis. Profilers like perf, py-spy, or async Tokio tracing consistently reveal that the actual bottleneck is a network call or a database query: not the runtime. Teams that skip profiling often rewrite a service and discover the p99 latency is unchanged because the bottleneck was elsewhere.

  • Treating Rust ramp-up as a concurrent activity. Engineers learning Rust while doing a production rewrite take 3–5x longer per feature than experienced Rust engineers. The ramp-up is a prerequisite, not a parallel track. Teams that don't account for this routinely miss their timelines by a factor of two.

  • Scoping the rewrite too broadly on the first attempt. The first Rust service in a new organization should be a non-critical, bounded system: a data pipeline, an internal tool, or a sidecar. This gives the team a real production ramp-up without exposing critical user paths to learning-curve bugs.

  • Ignoring the hidden cost of the FFI boundary. When calling Rust from Python or Go, the FFI boundary adds complexity: data serialization, error mapping, and debugging across language runtimes. Teams frequently underestimate this cost and over-invest in FFI integration rather than moving to a cleaner service boundary.

  • Conflating code quality improvements with performance improvements. "The existing codebase is messy" is a refactoring argument, not a rewrite argument. A Rust rewrite does not automatically produce cleaner code: it produces code in Rust, which can be just as messy if the team is not experienced.

  • Failing to define success criteria before starting. Without a clear target: "reduce p99 from 120ms to 20ms at peak load" : teams have no way to declare the rewrite complete or to make scope decisions during development. Define the success metric first; it will shape every other decision.


How Can a Bootcamp Accelerate the Rewrite Decision?

If the blocking factor is team Rust readiness rather than a business-case problem, structured learning is the right intervention. If you want a faster path from "we're evaluating Rust" to "we have engineers who can execute a rewrite," Rustify's 9-week bootcamp offers 1:1 coaching, production-focused exercises, and code review from engineers who have shipped Rust in production environments. Building Rust competency before committing to a rewrite reduces timeline risk and improves the quality of your ROI estimate.



Keep Reading

Frequently Asked Questions

In theory, yes. In practice, the question is whether the improvement justifies the cost. A service that works, scales, and doesn't have safety incidents is an asset : rewriting it is a liability until it pays off. Always quantify the expected gain against the expected cost before starting. The opportunity cost of the rewrite : what the team could have shipped instead : is real even when it's invisible on the ROI spreadsheet.

Maybe. First determine if the leak is in your code or a library. If it's in your code, Rust would prevent that class of bug. But diagnosing and fixing a memory leak in the existing language is often faster than a full rewrite. Profile first, consider a targeted fix, then evaluate a rewrite if the architecture is fundamentally flawed. Memory leaks in Rust are also possible through reference cycles in Rc<RefCell<T>> or through Box::leak : Rust prevents use-after-free and buffer overflows, not all resource management errors.

Almost never all at once. If you have a 200k-line Python backend, a full Rust rewrite is a multi-year project with enormous risk. The better path: identify the services that are genuinely bottlenecked, rewrite those, and leave the rest alone. At mature organizations, this typically means rewriting 5–15% of the codebase (the performance-critical core) in Rust, while the surrounding infrastructure, tooling, and business logic stays in the existing language.

Go is a valid alternative when the team is coming from Python or JavaScript, the rewrite is primarily for concurrency (not raw performance), and the team has 2–3 months rather than 6+ months to ramp up. Go is faster to adopt and has a larger hiring pool. Rust is the right choice when memory safety guarantees and maximum performance are both required. For most API services, Go delivers 90% of Rust's performance improvement with 40% of the adoption cost : a favorable tradeoff when team Rust readiness is low.

Quantify the problem first: document the current p99 latency, incident rate, or cloud spend. Run a proof of concept on one hot path : a 10x improvement in a benchmark is more convincing than any theoretical argument. Then present the ROI calculation with the break-even timeline. Frame it as a business decision, not a technology preference. Management approves investments with clear returns; they reject technology enthusiasm without economic justification.

In 2026, the US market for senior Rust engineers is competitive but not impossible. Salaries for senior Rust engineers range from $185K to $230K. Sources: Rust-specific job boards (rustjobs.dev), the #jobs channel on the Rust Discord, and referrals from the open-source community (Rust contributors are often open to industry roles). Alternatively, training existing systems engineers in Rust is often faster than hiring : a 3-month structured program can bring a proficient C++ or Go engineer to production-ready Rust.


Sources

Ready to Land a $80-120k Rust Job?