Skip to content
Apsan Works

Migrating Off Legacy Software Without a Big-Bang Cutover

The riskiest way to replace an old system is to switch everyone over on a single weekend. Almost none of that risk is necessary.

4 min read

The default plan for replacing an old system is usually some version of: build the replacement, pick a weekend, and switch everyone over at once. It has an obvious appeal, a single clean date after which the old system is simply gone, and it is close to the riskiest way to run a migration that actually matters to the business.

A big-bang cutover concentrates every possible failure into one weekend, with the old system already decommissioned and no calm way back if the new one has a problem nobody caught in testing. Almost none of that risk is necessary, and the alternative is not meaningfully slower.

Run both systems in parallel before either one is trusted alone

The core technique is unglamorous: for a defined period, both the old and new systems run against the same real inputs, and their outputs get compared. Nobody switches over on faith. The switch happens when the numbers agree, consistently, for long enough to mean something.

This is the same shadow-mode discipline covered in how to evaluate an AI agent before you trust it, applied to a migration instead of a model. The disagreements that show up during the parallel run are the valuable output, not a nuisance to get through quickly. Each one is either a bug in the new system or a case where the old system’s behaviour was less well understood than anyone realised, and both are far cheaper to find while the old system is still there to compare against than after it has been switched off.

Migrate by segment, not by feature

A natural instinct is to build the entire replacement, feature-complete, before anyone touches it. A better one is to identify a genuinely separable slice of the business, one customer, one region, one product line, and migrate that slice completely, watching it operate for real before touching the next one.

This is also where designing for migration from the start pays off. A system built with a clear seam between components, where a data source or an integration point can be swapped for its replacement without touching the code around it, turns a migration into moving one seam at a time instead of a rewrite. A WhatsApp platform we built has exactly this property deliberately: campaigns and message history are written against one schema that does not know which connector sits behind a given number, so a number’s underlying connection method can change without touching the code that runs campaigns against it. That kind of seam is what makes segment-by-segment migration realistic rather than aspirational.

Keep an export, always

Whatever data lives in the old system, people need a way to get it out in a form they can actually use, for as long as any part of the migration is still in progress and often for a defined period after. This sounds like an obvious safety net and it is the thing most migration plans quietly skip once momentum builds toward decommissioning the old system.

The value of a guaranteed export is mostly about trust during the migration itself, not disaster recovery. A team that knows it can get its data back into a familiar format if something goes wrong resists the new system far less than one that suspects the old data is already gone the moment the switch happens.

Decommissioning is a decision, not a deadline

The old system should come down when the evidence says it is safe, not when a plan drafted months earlier said it would. That evidence is the accumulated record of the parallel run agreeing, segment by segment, for long enough that the team responsible for the data would be comfortable defending the decision if asked.

This reframes the whole migration from a project with a fixed end date into a process with a real stopping condition. It usually takes about the same total calendar time as a big-bang plan would have, because the parallel-run period substitutes for the testing phase a rushed cutover skips anyway. The difference is that every day of that time, the business has a working system, and the day the old one finally comes down is the least eventful day of the entire migration, which is exactly what a good decommissioning should feel like.

We design systems with the next migration already accounted for. See how we approach applications, or read about the scope discipline that makes a segment small enough to migrate safely.

Tell us what is slowing you down

A short conversation is usually enough to tell whether this is a build, an automation, or something you should not do at all. We will tell you which.