The strangler migration that actually worked
Big-bang rewrites fail for the same three reasons every time. Here is the boring alternative that got a twelve-year-old storefront onto a modern stack without a maintenance window.
Every rewrite starts the same way. Someone opens the old codebase, recoils, and says the word greenfield. Six months later the new system is 80% done, the old one still runs the business, and the team is maintaining both.
We have done enough of these to have stopped arguing about it. The answer is almost always a strangler migration, and the reason is not technical elegance. It is that a strangler migration is reversible at every step.
What actually goes wrong
Big-bang rewrites fail for three reasons, in this order:
- Nobody knows what the old system does. Not the edge cases, not the undocumented cron job, not the customer who depends on the bug. You find out at cutover.
- The business does not stop. New requirements keep arriving. You are now building a moving target twice.
- There is one terrifying night. All the risk concentrates into a single window. Everyone knows this, so the window keeps getting postponed.
The shape of the alternative
Put a proxy in front of everything. Route by path. New code serves new routes; everything else falls through to the old system untouched.
Then move one route at a time, cheapest and least risky first. Each move is a normal deploy that can be rolled back in seconds. There is no night where everything is at stake.
The uncomfortable part is that you run two systems for months. Teams hate this. But you were going to run two systems anyway — the difference is whether you admit it and plan for it.
Sequencing matters more than tooling
We order routes by risk × traffic. Low-risk, high-traffic pages go first: they prove the infrastructure under real load while a mistake costs almost nothing. Checkout goes last, behind a feature flag, at 1% of traffic.
On the Kestrel migration this meant checkout moved in week seventeen of a twenty-week project. Everyone wanted it in week three, because it was the point of the project. Moving it last is why there was no downtime.
When not to do this
If the old system genuinely cannot be kept running — the platform is EOL, the licence expired, the host is gone — you do not have this option. Take the big bang and buy insurance in the form of a very long parallel-run period.
Otherwise: strangle it. Slowly, boringly, one route at a time.