Why Software Rewrites Fail and What Works Instead
Why Software Rewrites Fail and What Works Instead
Every few years, a team looks at the system running their business and concludes it should be replaced entirely. Modern technology, clean structure, none of the accumulated mess.
It is the most appealing option available and it has the worst record of any of them. The reason is specific and worth understanding, because it also points at what does work.
Legacy is an economic condition
First, a definition, because the word gets applied to a mainframe, to a ten-year-old monolith, and to a service written eighteen months ago by contractors who have since dispersed. Those are not the same problem.
A system is legacy when the cost of changing it has grown faster than the value of the changes.
That is deliberately economic rather than technical. Age is not the issue. Language is not the issue. A well-tested old system with people who understand it is healthier than an undocumented modern one whose authors have left.
The diagnostic follows: how long does a small change take to reach production, how often does a change break something unrelated, how many people can safely modify the core, and can someone build a working environment from nothing?
Four questions, one afternoon. And they tell you what to fix — because if changes are slow due to a two-week manual release process, rewriting the application gives you a modern application with a two-week manual release process.
What the old system knows
Here is the specific reason rewrites disappoint.
Your existing software contains years of corrections that exist nowhere else. Every odd rule is there because something went wrong once — a customer complained, a regulator asked a question, an edge case appeared at year-end and somebody patched it on a Friday.
None of it is documented. The people involved have moved on. Half of it predates the current ticket system.
It exists in exactly one place: as behaviour.
A rewrite discards all of it and rediscovers it one production incident at a time, over eighteen months, while stakeholders ask why the replacement is worse than the thing it replaced.
And because the business will not pause its roadmap, you maintain the old system while building the new one — so every change to the old moves the target the new one is aiming at. That is the mechanism by which rewrites reach three times their estimate. Structural, not incompetence.
When a rewrite genuinely fits
Three conditions, and you want all three:
- The system is small enough to fully understand in about a week
- The original technology has no viable forward path — genuinely unsupported or unhireable, not merely unfashionable
- The business changed so fundamentally that existing behaviour is a liability rather than an asset
Outside those, incremental replacement is cheaper and considerably safer.
What works instead
Put a routing layer in front of the existing system. Build replacements one component at a time and redirect traffic as each becomes ready. The old system shrinks gradually rather than being switched off in a single event.
Two things determine success.
Cut where the domain divides, not where the code separates easily. If the business talks about pricing, fulfilment and settlement as distinct things, those are candidate boundaries. A split that only makes sense to engineers gets argued about in every planning meeting afterwards. And check call frequency across the proposed seam first — extracting a component that chats constantly with the remainder converts fast in-process calls into network round trips and leaves you with a distributed monolith, which is strictly worse than what you started with.
Plan the ending at the beginning. These programmes stall at around seventy per cent with striking consistency, because the easy parts get done first, the pain is relieved, and the remaining core is the hardest work with the least visible benefit. Write down which component will be last and what it will cost, then ask whether it will still be funded once the urgency has gone. If the answer is no, you are building a permanent hybrid — a legitimate choice, but one to make knowingly.
What changed recently
The most expensive part of this work was never writing new code. It was understanding the old code — reconstructing intent from implementation, finding every place a rule is enforced. That was historically forty to sixty per cent of a programme, it did not parallelise, and only senior people could do it.
That specific task compressed hard. Models read unfamiliar code well and produce a coherent first draft of what it does, which a domain expert then verifies and corrects. The output is not trustworthy unreviewed — but verifying an explanation is far faster than deriving one, and that asymmetry is the entire saving.
Discovery phases that ran six months now run six weeks. If you hold an estimate written before 2024, that line is probably wrong in your favour by a lot, and re-running it is worth an afternoon before concluding a programme is unaffordable.
What did not change: deciding what the system should do, and resolving the places where the code and the business disagree. Those still need people with domain knowledge and authority — and they are now the bottleneck.
Where to start
Not with the worst component. It is worst because it is hardest, which means months with nothing visible, which is exactly when programmes get questioned at budget reviews.
Start with something painful, bounded, and visible to someone outside engineering. Deliver it, then use the credibility to fund the harder work.
Full guide with all seven modernization paths, data migration and cost modelling: Legacy Application Modernization. If you want an outside read before committing, we are happy to talk.
Frequently Asked Questions
What actually makes a system legacy?
Economics rather than age — the cost of changing it has grown faster than the value of the changes. A well-tested fifteen-year-old system can be healthy while an eighteen-month-old one whose authors left can be legacy.
Why do rewrites fail so consistently?
Because the old system holds years of corrections that exist only as behaviour, which a rewrite deletes and then rediscovers through production incidents. Meanwhile the business keeps changing the old system, so the target moves throughout the rebuild.
When is a rewrite justified?
When all three hold: the system is small enough to understand fully, the technology has no viable forward path, and requirements changed enough that existing behaviour is a liability. Otherwise incremental replacement wins.
What is incremental replacement?
A routing layer in front of the legacy system, with components replaced one at a time and traffic redirected as each is ready. Cut along business domain boundaries, and check that extraction will not turn frequent in-process calls into network calls.
Why do these programmes stall at seventy per cent?
Because the clean extractions come first and relieve the acute pain, leaving the hardest and least visible work with no urgency behind it. Name and cost the final component at the start as insurance.
Has AI changed the cost of this work?
The comprehension half substantially — reading unfamiliar code and drafting behavioural documentation that experts verify. Estimates predating 2024 typically overstate that line, and re-running them has been enough to change go/no-go decisions.
