Modernising a legacy system without switching it off

The rewrite that takes two years and ships nothing is the default outcome. Here is the alternative.

The short answer

Modernise a legacy system incrementally using the strangler pattern: put a new layer in front of the old system, move one capability at a time behind it, and retire the old code only when nothing calls it. Big-bang rewrites fail because the old system keeps changing while the new one is being built.

Key takeaways

  • Never freeze the old system for the duration of the rewrite — the business will not accept it.
  • Move one capability at a time, with the old and new running in parallel.
  • Data migration is the hard part; rehearse it repeatedly before the real cutover.
  • Document why the legacy behaves oddly before you replace it — the oddities are usually load-bearing.

The system is fifteen years old, the person who wrote it left in 2019, it runs on a version of PHP nobody wants to touch, and it processes every order the company takes. Turning it off is not an option and neither is leaving it.

Why the big-bang rewrite fails

You cannot freeze a business for eighteen months. While the new system is being built, the old one keeps acquiring features, exceptions and fixes — so the target moves continuously, the new system is permanently behind, and eventually the project is cancelled with nothing in production.

The strangler pattern, practically

  1. 01Put a routing layer in front of the legacy system. Everything still goes to the old code at this point.
  2. 02Pick the least entangled capability with the highest pain — often reporting or a customer-facing portal.
  3. 03Build that capability new, route its traffic to the new implementation, keep the old one available as a fallback.
  4. 04Verify in parallel: run both, compare outputs for a fortnight, and only then remove the old path.
  5. 05Repeat, slice by slice, until the legacy system serves nothing and can be switched off without ceremony.

Data is where the time goes

Fifteen years of a live database contains records that violate every rule the current schema assumes — nulls where nulls should be impossible, duplicates created by a bug fixed in 2017, encodings from two migrations ago. Budget for repeated dry runs, write reconciliation reports that compare old and new record by record, and expect the cleaning to take longer than the moving.

Document before you delete

Odd legacy behaviour is usually load-bearing. Before replacing a rule that looks wrong, find out which customer it exists for. The fastest way to lose trust in a modernisation programme is to fix something that was not broken for the one client whose contract depends on it.

Questions people also ask

Refactor when the architecture is sound and the code is untidy. Rewrite the capability, not the system, when the architecture itself blocks what the business needs — and do it in slices, behind a routing layer, so you are never betting the company on a single cutover.

Keep reading

Related

What this connects to

Rather have this answered about your own account?

Send us what you have. We will look at it properly and write back with what we would change, in the same plain terms as the page you just read.