A cautionary tale of rewriting everything in Rust, what went wrong, and why technical bets can sink a startup faster than bad code.
When you're inside a tech startup, it's easy to believe technology is the company. New frameworks, faster runtimes, and "modern stacks" feel like the secret weapons that will set you apart.
That's what we thought when we decided to rewrite our entire codebase in Rust.
It felt bold, visionary, and correct. Rust was safe, fast, and modern. Every developer on the team loved it.
And then — just 18 months later — the company folded.
This isn't an anti-Rust piece (I actually love Rust). It's a story about the wrong bet at the wrong time, how a rewrite consumed us, and what others can learn before making the same mistake.
How We Got Here: The Allure of Rust
At the time, our backend was written in a patchwork of Python and Node.js. It worked — but it was messy:
- Services slowed under load.
- Memory leaks caused outages.
- Developers cursed at async bugs and dependency hell.
Then came the hype around Rust. Every article promised:
- Zero-cost abstractions: as fast as C but safer.
- Fearless concurrency: no race conditions, no undefined behavior.
- Memory safety: goodbye leaks, hello guarantees.
We convinced ourselves: Rust is the future. If we rebuild in Rust, we'll leapfrog competitors.
The Decision to Rewrite
We debated incremental refactors versus a clean slate.
Incremental migration sounded "safe" but slow. Starting fresh in Rust sounded… heroic.
Here's the exact logic our CTO used:
"We're small now. Easier to rewrite now than when we're bigger. Let's take the hit once and be done."
It was seductive logic. Investors nodded, developers cheered. The board approved.
We nuked the old repo and started rewriting every service in Rust.
Life During the Rewrite
The honeymoon period was exciting. Rust forced rigor — no null pointer bugs, no sloppy lifetimes. Performance benchmarks looked promising.
But cracks soon appeared:
- Developer Velocity Cratered Rust's compiler is famously strict. New features that took days in Python stretched into weeks. Debugging lifetimes consumed hours.
- Hiring Dried Up Rust talent was scarce. We could find decent Python engineers in weeks. Rust engineers? Months. And the ones we found were expensive.
- Product Halted While competitors shipped features, we were still "stabilizing the Rust rewrite." Our customers didn't care about memory safety. They cared about features we stopped delivering.
Implementation Example: The Rewrite Pain
Take our event ingestion pipeline.
Python (original):
import json
from flask import Flask, request
app = Flask(__name__)
@app.route("/event", methods=["POST"])
def ingest():
event = request.json
process_event(event)
return {"status": "ok"}Naive, but it worked.
Rust (rewritten):
use actix_web::{post, web, App, HttpServer, Responder};
use serde::Deserialize;
#[derive(Deserialize)]
struct Event {
user_id: String,
action: String,
}
#[post("/event")]
async fn ingest(event: web::Json<Event>) -> impl Responder {
process_event(event.into_inner());
"ok"
}Beautiful. Safe. Performant.
But the rewrite required:
- A custom Kafka client integration.
- A bespoke error-handling layer.
- Async lifetimes debugging that took days.
The Rust version was rock-solid, but it took 5× longer to build and only marginally outperformed Python under our real-world loads.
Complexity Analysis: Rust vs Python
- Dev velocity: O(n²) overhead as features + borrow-checker complexity multiplied.
- Team scaling: O(n × t), where t = training time in Rust, much higher than Python.
- Performance gains: ~30% faster in microbenchmarks, but only ~10% in end-to-end workloads due to I/O bottlenecks.
The cold truth: The performance wins didn't justify the productivity loss.
Benchmarks We Ignored
When the first Rust services landed in prod, we ran benchmarks.

Yes, Rust was faster and leaner. But dev velocity plummeted.
Our customers never noticed the 20% speed boost. They did notice missing features.
Real-World Example: The Feature We Never Shipped
Our biggest customer asked for a Slack integration. In the old stack, it would've been a weekend hack.
In Rust, it turned into:
- Writing an async Slack client.
- Dealing with type safety on payloads.
- Debugging borrow-checker errors when reusing payload buffers.
It took six weeks. By then, the customer churned.
The Spiral
Here's how the spiral went:
- Developers slowed down → fewer features shipped.
- Customers churned → revenue dipped.
- Investors pressed for growth → team worked longer hours.
- Burnout hit → engineers left, hiring Rust replacements was slow.
- Runway shrank → no time to recover.
We had built the world's most performant, memory-safe codebase… for a company that no longer existed.
Lessons Learned
1. Technology ≠ Business
Customers don't care if your backend is Rust, Python, or carrier pigeons. They care about value. Our obsession with rewriting blinded us to what mattered.
2. Beware the Rewrite Trap
Joel Spolsky said it best: "The single worst strategic mistake is to rewrite from scratch." We ignored that advice. We paid for it.
3. Productivity Beats Purity
Rust is incredible — but only if its guarantees map to business value. In our case, Python's "good enough" performance + faster iteration would have kept us alive.
4. Hiring Market Matters
Tech isn't just about languages. It's about talent availability. By narrowing to Rust, we narrowed our talent pool.
5. Incremental Migration > Big Bang
We should've migrated hot paths (e.g., event ingestion) to Rust and left the rest in Python. That would have balanced speed with velocity.
What I'd Do Differently
If I could go back:
- Keep Python for 80% of the app.
- Rewrite only bottlenecks in Rust.
- Invest in monitoring, caching, and DB tuning before rewriting code.
- Treat Rust as a scalpel, not a sledgehammer.
Real-World Parallels
We weren't alone.
- Mozilla Servo: Ambitious Rust rewrite of a browser engine. Brilliant tech, but ultimately shelved due to cost.
- Dropbox: Tried Rust in some subsystems but didn't rewrite wholesale. Balanced practicality with adoption.
- Discord: Moved voice services to Rust incrementally, keeping core in Go and Python. That worked.
The winners were cautious. The losers rewrote everything.
Conclusion
Rust didn't kill our company. Our decision to rewrite everything in Rust did.
The lesson is bigger than Rust. Every tech team faces shiny rewrites: Go vs Java, serverless vs Kubernetes, microservices vs monoliths. The danger is forgetting that technology is a means, not the end.
Would I use Rust again? Absolutely. But I'd use it where it fits, not as a blanket rewrite strategy.
We rewrote everything in Rust. The code was beautiful. The company is gone.
Don't make the same mistake.
Ready to discuss.