Legacy Modernization: When to Rebuild vs. Refactor
December 8, 2023
The rebuild vs. refactor decision depends almost entirely on where the complexity lives in the system.
If the business logic is sound — if the rules the system enforces, the calculations it runs, and the data it manages are correct — then what you have is usually a presentation and architecture problem, not a logic problem. The underlying model is right. The way it's been built around is what makes changes hard. That's a refactoring problem.
If the business logic is itself the mess — if nobody can explain why the system makes the decisions it makes, if rules have been hardcoded in ways that contradict each other, if the data model has drifted so far from what the business actually needs that every query is a workaround — that's a different situation. The problem isn't that the architecture is ugly. The problem is that the system has accumulated incorrect behavior over time and carries it as load-bearing code.
Refactoring that second situation is expensive and often futile. You're cleaning around the problem, not addressing it.
What Gets Underestimated in Both Directions
Refactoring projects underestimate the cost of context. Understanding a system well enough to improve it safely requires knowing what it does, which requires time that rarely shows up in estimates. The estimate covers the refactoring work. The archaeology that makes the refactoring safe is implicit, assumed to be fast, and usually isn't.
Rebuild projects underestimate what the legacy system actually does. The documented requirements describe the intended behavior. The actual behavior includes fifteen years of edge cases, integration quirks, business rule exceptions that were added without ceremony and exist for reasons nobody now alive can explain. The new system won't have those. Users will find them.
The hybrid approach — replace the architecture while preserving the logic — is often the right answer and is rarely what either "rebuild" or "refactor" means in practice. Extract the business logic from the legacy system, characterize it with tests that document actual behavior, and build new infrastructure around it. You get modern deployment, modern tooling, and a maintainable codebase, without betting that you've rediscovered all the edge cases from scratch.
The decision about which path is right depends on an honest assessment of which category you're in. That assessment is worth doing carefully before committing to either.
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