Engineering
When not to rewrite a legacy application
A rewrite is the most expensive available method for discovering what your current system actually does.
The case for a rewrite is almost always made with adjectives. The system is old, brittle, unmaintainable, a mess. None of those are measurements, and none of them tell you what will be better afterwards.
The case against is usually made with one observation: the existing system encodes a decade of decisions that nobody wrote down, and a rewrite proposes to rediscover all of them under a deadline.
Name the constraint or do not start
- A change that should take a day takes three weeks — where, specifically, does the time go?
- Releases are rare — is that the architecture, or the deployment process?
- Performance is degrading — is it the data model, the queries, or the volume?
- Nobody understands module X — is that a rewrite, or two weeks of reading and a document?
The cases where a rewrite is genuinely right
There are real ones. The runtime is unsupported and unpatched. The data model contradicts the business the company now runs. The system cannot be deployed without downtime and that has become commercially unacceptable. In each of those, the constraint is structural and no amount of incremental work reaches it.
| Symptom | Usually | Occasionally |
|---|---|---|
| Slow to change | Missing tests, unclear ownership | Genuine coupling |
| Slow at runtime | Query and index problems | Wrong data model |
| Frequent incidents | No observability | Fundamental fragility |
| Nobody wants to work on it | Tooling and onboarding | Language or runtime is dead |
The middle path is not a compromise
Routing new work through a new implementation while the old one keeps serving what it already serves is not half a rewrite. It is the version that can be stopped halfway and still leave the business better off — which is the only property that matters when the estimate turns out to be wrong.
Related reading