Blog · Architecture ·

When to refactor and when to rebuild

"Rewrite it" is the most expensive answer in engineering. It's sometimes right. More often it's a decision made in frustration. Here are five questions we ask before we recommend either path.

1. Is the model still right?

Refactoring is changing how the code does what it does. Rebuilding is changing what the code does. If the underlying domain model still represents your business, refactor. If your customers, business rules, or scale have outgrown the model itself, no amount of cleanup will save you.

2. Can you ship value during the work?

A rebuild that takes 18 months and ships no customer-visible value is a project that gets killed in month 14. The best rewrites ship behind feature flags, route traffic incrementally, and deliver wins along the way. If you can't sketch a plausible "month 3 win, month 6 win," reconsider.

3. What's the test coverage actually like?

Refactoring without tests is a coin flip. Rebuilding without tests is a coin flip with a bigger coin. If coverage is thin, your first move (regardless of path) is to characterize the existing behaviour with tests — golden-master, contract, or property-based, whichever fits.

4. How much of the code is load-bearing legacy vs accidental complexity?

Most legacy systems are 30% essential complexity (real domain rules) and 70% accidental complexity (workarounds for bugs nobody remembers, scaffolding for features nobody uses). Refactor the essential parts; delete the accidental parts. A rebuild often re-creates the accidental parts because nobody reads the old code to find out what's actually needed.

5. Who owns the new system after launch?

If the team that will own the new system isn't building it, you're not rebuilding — you're outsourcing your future tech debt. The strongest predictor of a rebuild succeeding is whether the team running prod the day after launch is the same team that made the architectural decisions on day one.

Heuristics we use

  • Refactor when: the domain model is still right, tests exist or can be added, and the pain is concentrated in 1–2 modules.
  • Strangle (incremental replace) when: the domain is mostly right but the framework/runtime/data-store is wrong. New surface area gets the new stack; legacy code keeps running until it's replaced.
  • Rebuild when: the domain model is wrong AND the cost of working around it is higher than the cost of starting clean. Rare, but real.

The honest answer for most engagements: strangle. Not as exciting as a clean-slate rebuild, but far less likely to end in a project graveyard.


If you want a written assessment of your codebase with a recommended path, we run two-week application review engagements ending in an architecture decision record you can show your team and your board.

Stuck between refactor and rebuild?

Tell us what the system does and where the pain is. We'll respond within one business day with how we'd approach it.

Book a code review