What a Rewrite Costs Beyond the Estimate

August 12, 2024

Rewrite estimates are built against documented requirements. Production systems implement documented requirements plus years of undocumented behavior, and the gap between the two is where rewrite budgets go.

The proposal follows a consistent sequence. A team inherits a system built by people who have left. After several weeks of investigation, someone observes that the code is hard to follow, the framework is out of support, and building fresh with current tooling would be faster than untangling what exists. The reasoning is sound given the information available. The information available is the problem.

What the legacy system contains that the specification does not

Legacy complexity accumulates for reasons that are not recoverable from the code, and each instance represents a requirement discovered in production.

  • Incident-driven conditionals. The unexplained branch exists because a specific input caused a specific failure with a specific cost. The branch is the fix. The incident is not documented.
  • Load-driven design. The caching layer that appears overengineered replaced a simpler approach that failed under real traffic.
  • Integration compensation. The workaround in the billing path exists because a downstream system behaves incorrectly under a particular condition and will not be changed.
  • Regulatory encoding. Rules that look arbitrary implement a compliance requirement someone received by email in 2017.
  • Data quality handling. Defensive code accommodating historical records that violate current constraints, written before the constraints existed.

None of this appears in requirements documentation. It is in the code, and the code is correct.

How the overrun materializes

The failure sequence is consistent across rewrite projects and does not depend on team quality.

  1. The new system is built against documented requirements and passes its acceptance tests.
  2. It goes live, usually in parallel or by segment.
  3. Users report results that differ from the old system for specific cases.
  4. Each case is investigated individually, the underlying rule is identified from the legacy code, and the rule is implemented.
  5. The project extends by the time required to rediscover the undocumented behavior — empirically, from the people affected by getting it wrong.

Step 5 has no upper bound available at estimating time. The team does not know how many such behaviors exist, because if it knew, they would have been in the specification.

The secondary cost is organizational. Steps 3 and 4 consume credibility with the business at exactly the point where the project needs support to finish.

Incremental migration and why it holds up

Building a new layer around the existing system and replacing capability by capability changes the risk profile in two ways that matter.

  • Discovery precedes replacement. A capability cannot be migrated without first establishing what it does, including the edge cases. The investigation that the rewrite defers to production is performed before the switch, on one component at a time, with the legacy implementation available as the reference.
  • There is a shippable system at every point. If priorities change or funding stops, the result is a partially modernized working system rather than an unfinished replacement that cannot be deployed.

The practical mechanics: route traffic through a facade, move one capability behind it, run old and new in parallel comparing outputs on production traffic, then cut over when the outputs agree. Output comparison on live traffic is what surfaces the undocumented behavior, and it surfaces it without a user experiencing it.

Where a rewrite is the correct call

Three conditions justify it, and they are narrower than the frequency of rewrite proposals suggests.

  • The platform is genuinely dead. No supported runtime, no upgrade path, no developers available. Web Forms front ends and unsupported proprietary frameworks qualify.
  • The business model has changed enough that the existing rules no longer apply. If most of the encoded behavior is behavior the business no longer wants, preserving it has negative value.
  • The system is small enough that full behavioral discovery is tractable. Discovery is bounded, so the estimate can include it.

The question before committing

Before approving a rewrite, establish what accounting has been done for production behavior as opposed to designed behavior.

A defensible answer names the discovery method: production log analysis, output comparison against the legacy system, characterization tests built from real transaction data. An answer that references the requirements documentation has not addressed the risk, and the estimate attached to it is measuring the wrong system.


Working through a problem like this?

Describe the system and where it's stuck. I'll tell you what the work actually involves.

Get in touch