The Strangler Pattern in Practice: Replacing a System Without Stopping It
Big-bang rewrites fail for reasons that are structural, not managerial. How to route traffic away from a legacy system feature by feature, reversibly.

Every rewrite begins with the same reasoning: the old system is unmaintainable, we understand the domain now, we will build it properly. Two years later the replacement is still catching up on business rules the original accumulated over a decade, and the business has not stood still. The strangler pattern exists because that arithmetic almost never works.
Why rewrites fail structurally
A rewrite requires the new system to reach feature parity with a moving target before it delivers any value. Meanwhile the old system still needs changes, so you maintain two codebases with one team. The failure is not poor execution — it is that the plan requires a period of zero delivery, and organisations cannot sustain that.
A rewrite asks the business to accept two years of nothing in exchange for a promise.
Insert a seam first
Before migrating anything, place a routing layer in front of the legacy system — a gateway, a proxy, a facade. Every request passes through it, and initially every request goes straight to the old system. Nothing has changed functionally, but you have bought the ability to redirect any individual route later, which is the entire foundation.
Characterise before you change
Undocumented behaviour in a long-lived system is usually load-bearing. Write tests that capture what it currently does, including the parts that look like bugs — some downstream process may depend on them. These characterisation tests are your safety net, and writing them teaches you the domain faster than reading the code.
Run both and compare
For critical paths, send the request to both implementations, return the legacy result, and log the difference. This is the highest-confidence migration technique available: you discover discrepancies with real production traffic while users are still served by the system known to work. Only when differences reach zero for a sustained period do you switch the response.
Data is the hard part
Routing requests is straightforward; moving the data underneath is not. The usual approach is dual-write during transition with reconciliation to catch drift, then a read cutover, then a write cutover. Expect this to take longer than the application work, and plan the reconciliation tooling as a deliverable rather than a script someone writes under pressure.
Retire on evidence
The last step teams skip is switching the old path off. Instrument the legacy routes so you can prove nothing calls them, then remove them. An unremoved legacy path is a system you are still maintaining and still paying for, and it will be depended upon again if you leave it available.





