POST
The rewrite math
Aug 20266 MIN READ
The phrase "never rewrite from scratch" gets quoted with the authority of a law of physics, and like most laws quoted in software, it is really a heuristic with a complex history. It comes from a famous essay about why Netscape's rewrite nearly killed the company, and the lesson everyone took was the wrong one. The essay was not about rewrites being evil. It was about a rewrite that was actually a rewrite of a product that was still succeeding, done in secret, with no honest accounting of cost.
I have been in rooms where "never rewrite" ended the discussion and saved a project from disaster, and I have been in rooms where it condemned a team to years of slowly drowning. The distinction is not the word "rewrite". It is the math, and most teams never actually do the math.
Why the old code is so expensive
Before you can reason about a rewrite, you have to reason about the thing you are proposing to replace. The uncomfortable truth is that old code is expensive for reasons that have nothing to do with its quality. It carries the accumulated history of the product: the features added after the original design was drawn, the integrations nobody remembers wiring, the edge cases discovered by production incidents. Every one of those has a corresponding test, or a corresponding scar, and often both.
This is why a rewrite that "keeps the same features" always takes longer than expected. The author of the rewrite looks at the current behavior, sees what the code does today, and rebuilds that. What they cannot see is all the behavior that is not currently exercised, the code paths that run once a quarter, the integrations that are tested by the support team's muscle memory. The old codebase is not just a pile of bad code. It is the executable form of everything the team has learned. Rewriting it from scratch means paying to learn it all again.
The math you actually do
The honest comparison is not "old code vs new code". It is "keep improving the old code" versus "rewrite, and then keep improving the new code". Both paths are open, and the deciding variable is how much of the old code's cost is structural versus incidental.
Structural cost is the part that will not go away with more patches. The database schema that cannot model the product anymore. The monolith that cannot deploy without a full regression run. The language that no one on the team wants to write. Incidental cost is the part that would go away with focused effort: the slow test suite, the missing documentation, the tangled function that a refactor would untangle. Rewriting to escape incidental cost is paying a fortune to avoid a parking ticket.
The math, roughly, is: estimate the cost of the rewrite, including the relearning and the lost feature velocity while it happens, and compare it to the cost of removing the structural pain from the old system, piece by piece. Most of the time the second number is smaller, which is why the heuristic exists. Sometimes the first number is smaller, which is why the heuristic is not a law.
The rewrite that is not a rewrite
The most successful "rewrites" I have seen were not rewrites at all. They were strangler fig operations: replace the old system one slice at a time, behind an interface, until the old system is a small thing that can be deleted. The new system grows alongside the old one, and at every moment, something works.
This approach has a killer advantage beyond risk. It converts the rewrite from a big bang into a series of small bets, and small bets can be evaluated. When you replace the payment slice and the numbers look good, you keep going. When you replace the reporting slice and discover the old reporting had a quirk that three customers rely on, you have lost one slice, not the project. A big bang rewrite discovers that quirk on launch day, in production, with the old system already deleted.
The interface between old and new is the whole engineering challenge of the strangler approach, and it is the part that is always harder than it looks. The old system was never designed to have a clean boundary. Finding one, or carving one, is where the project lives or dies.
When the rewrite is the honest answer
I have seen rewrites that were obviously right, and they share a shape. The product is changing direction, not just improving. The existing system cannot express the new model without being bent so far out of shape that the bend is the whole project. The team is small and the new system is small. The old system has no hidden gold, because it was written recently, badly, by people who no longer work there, with no tests and no users to lose.
The other case is the constrained rewrite: keep the data, keep the integrations, keep the tests as a specification, and rewrite the implementation. This is the version that uses the old codebase as the world's most detailed spec. The team that does this is not writing from a blank page. They are translating, and translation is a completely different risk profile from creation.
The questions that decide it
If you are in the room where someone proposes a rewrite, here are the questions worth asking. What structural cost is the old code imposing, exactly, and can that cost be removed in place? What hidden behavior does the old system have, and how will the rewrite discover it? What happens to feature development during the rewrite, and does the business survive that? Who has to be right for this to work, and what happens if they are wrong?
If the answer to the structural cost question is vague, the rewrite is based on feeling, not math. If the hidden behavior question cannot be answered with a plan to find out, the rewrite is a bet on ignorance. If the business cannot survive the feature freeze, the rewrite has a cost the team is not counting.
The version nobody quotes
The essay that everyone quotes as "never rewrite" actually ends with a much more interesting claim: the wise approach is to rewrite a system in pieces, to keep the old system alive while the new one grows, and to treat the old code as a valuable artifact to learn from, not an enemy to destroy.
The wisdom is not "never rewrite". It is "never rewrite blindly". Do the math, name the structural cost, preserve the hidden knowledge, keep something working at every step, and make the decision with your eyes open. The word rewrite is not the problem. The silence about the tradeoff is.