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.

What the symptom usually indicates
SymptomUsuallyOccasionally
Slow to changeMissing tests, unclear ownershipGenuine coupling
Slow at runtimeQuery and index problemsWrong data model
Frequent incidentsNo observabilityFundamental fragility
Nobody wants to work on itTooling and onboardingLanguage 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.

Working on something this applies to?