Rewrite roulette: 'let's just rebuild it' is debt denial with a project plan
There is a moment in the life of every debt-soaked codebase — you may be living it right now — when someone in a meeting leans back and says the five most expensive words in software: "Let's just rewrite it."
And everyone exhales. Because the rewrite is such a seductive idea. No more archaeology. No more fear of the module nobody understands. A green field! Modern framework! We know so much more now! The rewrite feels like paying off the debt in one heroic lump sum.
Here's the thought experiment that should run in that meeting before anyone opens a project tracker. Your house is cluttered. The closets are chaos, the wiring is weird, there's a light switch that does nothing (there's always a light switch that does nothing). So you burn the house down and build a new one. Two observations: first, you still own all the same stuff — it's now in boxes, in the rain, and you've forgotten which box holds the passports. Second, the new house will have its own switch that does nothing within eighteen months, because the force that produced the clutter was never the house. It was you, living in it, under deadline.
The oldest warning label in software
The rewrite impulse has been studied for fifty years, and the findings have never changed. Fred Brooks, in The Mythical Man-Month, named the second-system effect: the second system a designer builds is the most dangerous one they will ever design, because into it goes every idea, every generalization, every frill they prudently deferred the first time. The rewrite is, definitionally, a second system — undertaken at the exact moment the team's confidence ("we know so much more now!") is at its maximum and its humility at its minimum. Brooks was describing OS/360 in 1975. He was also describing your Slack thread from last Tuesday.
Joel Spolsky made the commercial version of the argument in his essay "Things You Should Never Do, Part I," writing about Netscape's decision to rewrite its browser from scratch — a choice he called the single worst strategic mistake a software company can make, and one that coincided with Netscape handing its market to a competitor while shipping nothing. His core mechanism is the one that matters here: the old code looks awful because code is harder to read than to write, and those ugly patches you're sneering at are not entropy — they are knowledge. That two-line hack handles the date bug that only fires in Sydney during daylight-saving transitions. That weird retry wrapper exists because the payment vendor lies about timeouts on Tuesdays. Each one was paid for with a production incident, and the rewrite proposes to un-learn all of them simultaneously, then re-learn them the same way they were learned the first time. In production. From your customers.
What actually burns in the fire
Peter Naur's "Programming as Theory Building" gives the deepest version. The real program, Naur argued, is not the text — it's the theory in the builders' heads: why things are shaped this way, what will break if you push there. Now notice the cruel asymmetry of the rewrite. By the time a team is desperate enough to propose one, the theory of the old system is already half-dead — original authors gone, decisions unrecorded, and (this being 2026) a meaningful share of the code drafted by models that never held a theory at all. The rewrite doesn't restore the theory. It discards the surviving fragments — the battle-tested fixes, the encoded incident history, the ten thousand small corrections — and replaces them with a brand-new system about which the team holds a theory that is complete, coherent, and untested against reality. You traded a tattered map of real terrain for a beautiful map of imaginary terrain.
A rewrite doesn't retire your debt. It refinances it with a new lender — the future — at an interest rate nobody has quoted you yet.
Let's do the accounting honestly, in three lines:
- Debt you retire: the structural mess of the old system. Real! Genuinely gone!
- Debt you re-borrow: every requirement the old system satisfied that nobody wrote down — which, per Naur, is most of them. Each will be rediscovered as a "regression," one incident at a time.
- Debt you newly originate: the second-system frills (Brooks), the corners cut when the rewrite runs late (all rewrites run late), and — new for the AI era — a few hundred thousand generated lines that arrive already wearing the wince-free debt from Part 21, at a volume the old system took years to accumulate.
Net position: usually negative, always unknown. That's the roulette. Sometimes the ball lands on black and the rewrite works — it does happen, and survivors write triumphant blog posts, which is exactly what survivorship bias looks like. The failures write postmortems, or nothing.
The tell: a rewrite proposed without numbers
Here's the diagnostic that separates a legitimate rebuild from debt denial. Ask the proposer three questions. Which parts of the current system carry the production load? Which parts are actually fragile — measured, not vibes? What fraction of the code would we be rewriting that nothing even calls?
If those answers exist, you can have a rational conversation — and it usually ends somewhere much cheaper than a rewrite, because the numbers keep telling the same story: the intolerable system is intolerable in a few specific, high-traffic places, embarrassing-but-harmless in many dormant ones, and quietly fine everywhere else. (In the CodeNSM fleet telemetry this pattern is near-universal — load concentrates on a small minority of functions, and a nontrivial share of what a rewrite would lovingly reimplement is code production never calls at all. Rewriting dormant code is paying movers to pack empty boxes.) The rational move is almost always the strangler-fig path: measure, rank the fragile-and-load-bearing intersection, rebuild those pieces incrementally behind stable seams, delete the dormant mass instead of porting it, and leave the boring, working middle alone. That's not timidity — it's the portfolio logic of Part 22 applied to reconstruction: retire the debt with the highest interest first, keep the loans that cost nothing, and never pay to rebuild what you could pay nothing to delete. Teams that run rebuilds this way get the one thing the big-bang version never delivers: a system that is improving while it still exists.
If those answers don't exist — if the case for the rewrite is "everyone hates working in it" — then what's being proposed isn't engineering strategy. It's debt denial: the fantasy that a debt too painful to itemize can be escaped by changing addresses. The debt collector has your forwarding address. He always does.
The AI-era accelerant
One closing worry, because it's coming for everyone: LLMs have made rewrites feel cheap. A model will happily regenerate your entire service layer over a weekend, and the demo will gleam. But look at what that actually is, through this series' lens: the maximum-velocity origination of borrower-less debt (Part 21), reviewed at a volume no human process can honestly cover (Part 5, and Bacchelli and Bird's review research long before that), replacing code whose surviving theory-fragments get deleted in the same commit. The rewrite used to be expensive enough that you had to think first. Now the roulette wheel spins for free — and only the bets are real money.
The house always was the cheap part. It's the knowledge inside that you can't afford to rebuild.
References
- Brooks, F.P. (1975/1995). The Mythical Man-Month: Essays on Software Engineering — the second-system effect.
- Spolsky, J. (2000). Things You Should Never Do, Part I.
- Naur, P. (1985). Programming as Theory Building.
- Bacchelli, A. & Bird, C. (2013). Expectations, Outcomes, and Challenges of Modern Code Review. ICSE / Microsoft Research.