When a system stops feeling good to work in, two answers get proposed in roughly equal measure.
"We need to refactor this."
"We need to rewrite this."
These aren't the same project. They have different costs, different risks, different timelines, and different ways of failing. Choosing wrongly between them is one of the most expensive mistakes an organization can make with its software.
This article is a diagnostic, not a polemic. It doesn't argue for one over the other. It maps the signals that point to each, so the decision can be made on evidence rather than mood.
What "Refactor" Actually Means
Refactoring is changing the internal structure of a system without changing what it does.
Done well, refactoring:
Improves clarity without changing behavior
Happens incrementally
Is verifiable at every step
Is low risk if scoped correctly
Compounds over time
A team that refactors continuously rarely needs a rewrite. A team that doesn't refactor at all usually ends up debating one.
The fuller treatment of this discipline is in What Is Incremental Refactoring? and Why Incremental Refactoring Beats Rewrites.
What "Rewrite" Actually Means
A rewrite is replacing the system with a new implementation, often on a new stack, that delivers the same or similar functionality.
A rewrite is:
Long
Expensive
High risk
Vulnerable to scope creep
Often less complete than expected when launched
Rewrites can be the right answer. They're also the most reliably overestimated project in software, on both timeline and outcome.
The choice between refactor and rewrite isn't "which one sounds better." It's "which one fits the actual state of the system."
Signals That Point to Refactor
A refactor is usually the right answer when:
1. The system still does the right things
The behavior is mostly correct. The features still match the operation. The problem is shape, not capability.
2. Most of the codebase is still legible
A new engineer can be brought up to speed in days or weeks. The architecture hasn't collapsed.
3. The pain is concentrated in specific areas
A few modules are responsible for a disproportionate share of bugs and slow changes. The rest of the system is fine.
4. The technology stack is still appropriate
The platform, language, and framework still match the needs of the system and the team.
5. The team has the ability to ship incremental changes safely
Tests exist. Deployment is routine. Incremental change is feasible.
If most of these are true, a refactor is almost always the right answer. Even when the urge to rewrite is strong, the math rarely supports it.
Signals That Point to Rewrite
A rewrite is usually the right answer when:
1. The system no longer does the right things
The behavior is wrong. The features no longer fit the operation. Bolting new shapes onto the old system has stopped working.
2. Large parts of the codebase are illegible
New engineers take months to be productive. Architecture is implicit or contradictory. Reading the code doesn't reveal what it does.
3. The pain is spread across the entire system
There are no calm areas. Every module is partially broken in its own way. The cost of change is uniformly high.
4. The technology stack is genuinely no longer fit
The platform is unmaintained, the framework is abandoned, the language is no longer hireable, or the dependencies are stuck on versions with security issues.
5. The team has tried incremental change and it hasn't worked
Refactoring efforts get stuck. Changes regress. The system actively resists improvement.
If most of these are true, a rewrite may be unavoidable. The bar is high, and it should be.
The Most Common Misdiagnosis
The most common misdiagnosis is calling for a rewrite when the actual problem is refactoring debt.
The signal:
The system does the right things, but doing them feels slow
Changes are painful, but the pain is concentrated
Engineers complain about the codebase but can't point to specific failures of capability
This is almost always a refactoring problem. The right answer is to refactor, often aggressively, and to recover the system rather than replace it.
The reverse misdiagnosis exists too, where teams refactor a system that genuinely needs replacement, but it's rarer.
Why Rewrites Often Fail
Even when a rewrite is the right answer, the project frequently underdelivers. The reasons are predictable.
1. The Old System Knows More Than Anyone Realizes
Years of small fixes, edge case handling, and operational compromises are encoded in the existing code. The rewrite team rediscovers them one outage at a time.
2. Scope Creeps Without Limit
A rewrite invites every wish list. Every feature that was hard to add in the old system becomes a requirement for the new one. The project bloats.
3. The Business Can't Wait
The old system has to keep running while the new one is built. The team is now maintaining two systems. Pace suffers.
4. The New System Inherits the Old Operation
If the operation that produced the old system hasn't changed, the new system will accumulate the same problems on a different stack.
Why Refactors Often Fail
Refactors fail less catastrophically, but they fail too. The reasons are also predictable.
1. The Refactor Becomes a Side Project
Without protected time, refactoring gets squeezed out by feature work. Progress stalls. Nothing changes.
2. The Refactor Isn't Scoped
Refactors that try to clean up "the whole system" rarely succeed. Refactors that target one painful area at a time usually do.
3. The Team Doesn't Trust Tests
Without confidence in tests, refactors stall. Engineers refuse to touch the painful areas because the risk feels too high.
4. The Underlying Architecture Can't Support Improvement
This is the case in which refactoring is genuinely the wrong tool. If the system can't be improved incrementally, the rewrite conversation is real.
The Middle Path: The Partial Rewrite
For many real systems, the right answer is neither full refactor nor full rewrite. It's replacing one part of the system at a time, with new implementations, while the rest continues to run.
This works when:
The system has clear seams
One subsystem is genuinely beyond saving
The rest is still serviceable
The team has the discipline to keep scope narrow
The partial rewrite is the most expensive choice in the short term and the cheapest in the long term. It avoids the failure modes of both alternatives.
A Simple Test
Ask three questions honestly.
Does the system still do what the organization needs?
Is the pain concentrated, or distributed?
Has incremental change been tried, with discipline, and failed?
Yes, concentrated; no, refactor.
No, distributed; yes, rewrite.
Mixed: partial rewrite of the worst subsystem.
The decision should follow the answers.
What This Looks Like in Practice
A healthy organization revisits this question every few years, calmly, with evidence. The signals that point to refactor are noticed early and acted on before they become signals that point to rewrite.
An unhealthy organization avoids the question until the system is in crisis, at which point a rewrite is proposed under pressure, scoped badly, and delivered late.
The choice between refactor and rewrite isn't where the failure happens. The failure happens earlier, in the years of avoided maintenance that turned a refactor into a rewrite conversation.
A Simple Rule of Thumb
If the team can name the three worst modules and the system works fine outside them, refactor.
If the team can't name the three worst modules because everything is roughly that bad, rewrite is on the table.
If the team isn't sure, refactor first and reassess in six months. The answer will be clearer.
Final Thoughts
Refactor and rewrite aren't interchangeable strategies. They're different responses to different states of a system.
Refactor when:
The behavior is right
The codebase is mostly legible
The pain is concentrated
The stack is still appropriate
Incremental change is possible
Rewrite when:
The behavior is wrong
The codebase is illegible
The pain is everywhere
The stack is no longer fit
Incremental change has been tried and failed
Most systems that get rewritten could have been refactored. A few that get refactored should have been rewritten. The error rate goes down sharply once the diagnostic is made on evidence rather than instinct.
The system itself will tell you which one it needs. The harder part is being honest about what it's saying.
If your team is staring at a system and trying to decide between refactor and rewrite, this is exactly the kind of decision we help engineering leaders work through without pushing toward either answer. Book a short consult.