
Replacing a system that people depend on every day has an obvious problem: the replacement is only useful when it is finished, and until then you are spending money on something nobody can use. The strangler pattern exists to break that property. Instead of one switch at the end, you move capabilities across one at a time, and the old system shrinks until there is nothing left worth keeping.
The name comes from the strangler fig, which grows around a host tree, takes over its position, and is self-supporting by the time the host is gone. It is a reasonable metaphor and a slightly misleading one — the real work is not organic at all, it is a sequence of deliberate, reversible extractions.
What the pattern actually is
Three mechanisms, in order.
A routing facade. Something sits between consumers and the legacy system: an API gateway, a reverse proxy, a service layer, occasionally a message broker. Every request goes through it. On day one it forwards everything to the old system and changes nothing observable — that is the point. Its value is that from then on you can change where a request goes without touching the caller.
Extraction, one capability at a time. Build a replacement for a single capability. Route that capability’s traffic to the new implementation. Leave everything else alone. The old system continues to serve the rest, unaware.
Retirement. Once nothing routes to a piece of the old system, delete it. This step is skipped more often than any other, and skipping it is how organisations end up with three systems instead of one.
Put crudely: the facade lets you lie to callers about where their request is handled, and that lie is what buys you the ability to move in stages.
Why incremental replacement de-risks
Value arrives before the end. The first extracted capability is in production within weeks. If the programme is cancelled after a third of the budget, you keep a third of the benefit — which is not true of a rewrite, where cancellation at any point before cutover yields nothing.
Failures are small and reversible. When an extraction goes wrong, one capability misbehaves. The facade can route it back to the old implementation, which is still there and still working. Compare that with a cutover, where the failure mode is the whole business at once and the fallback has already been decommissioned.
You learn with real traffic early. Assumptions about load, data quality, concurrency and user behaviour get tested on the first extraction, when correcting them is cheap. In a rewrite the same assumptions are tested at go-live, when correcting them is not.
The old system keeps receiving changes. Regulatory and commercial changes still have to be made somewhere, and with a strangler approach they are made once, in whichever system owns that capability at that moment. In a long rewrite they are made twice for the whole duration.
Comparison is possible. For a period you can run both implementations against the same input and compare outputs — a shadow read that finds discrepancies before users do. That option only exists while both systems are alive.
The costs people underestimate
The pattern is sound; the estimates around it usually are not. Four costs get left out.
You are running two systems
Two deployment pipelines, two monitoring setups, two on-call surfaces, two sets of dependencies to patch, and engineers who must hold both models in their heads. This is the permanent overhead of the transition period, and the transition period is usually longer than planned.
It also means the old system cannot be neglected. Its infrastructure still needs patching, its certificates still expire, and a security incident there is a security incident regardless of how much has moved. The security posture of the estate is the union of both systems, not the better of the two.
Data synchronisation is the real complexity
Splitting behaviour is straightforward. Splitting data is not. When the new customer service owns customer records but the legacy billing module still reads them, something has to keep both truthful.
The options are all imperfect: dual writes, which fail partially and leave inconsistency; change data capture, which is more robust but introduces lag; or the new system reading from the old database directly, which is expedient and quietly couples the replacement to the schema you were trying to escape.
The rule that keeps this tractable is single ownership: for each entity, exactly one system is the master at any moment, and the other holds a copy it may read but never write. Ambiguity here produces the failure that damages trust most — two screens showing different numbers for the same thing — and once users see that, adoption of the new system becomes a political problem rather than a technical one.
The facade accumulates logic
It starts as routing. Then one caller needs a field the new service does not return, so the facade fills it in. Then the response shapes differ, so it translates. Then a request needs both systems, so it orchestrates and merges. Eventually the facade holds business rules, and it is a third system that nobody planned, tested or documented.
Watch for it deliberately: translation is acceptable, routing is its job, business decisions are not. When a rule must live in the facade, treat it as scaffolding with a removal date attached to a specific extraction.
The end requires discipline that beginnings do not
The first extractions are motivating. The last ten percent is unglamorous work on the least attractive parts of the old system — the ones left until last precisely because they were hardest. Attention drifts to new products, and the transition stops one step short of completion.
A half-strangled system is the worst outcome available: all the overhead of two systems, permanently, with none of the simplification. Guard against it by tracking retirement rather than delivery — what fraction of the old system’s traffic, code and infrastructure is gone — and by naming the decommissioning date as a deliverable from the start.
Choosing what to extract first
The first extraction sets the pace, proves the facade and teaches the team. Choose it on these criteria, roughly in this order:
- Loose coupling. Few dependencies in either direction. A capability entangled with everything is a poor place to learn.
- A clear data boundary. Entities this capability can plausibly own outright. If the first extraction requires bidirectional synchronisation, pick another.
- Real, visible pain. Something users complain about or the business wants changed. Extractions that improve nothing anyone notices are hard to keep funded.
- Read-heavy before write-heavy. Reads are easier to run in parallel and compare, and a wrong read is less damaging than a wrong write.
- Meaningful but not existential. Big enough to prove the approach, small enough that a bad week is survivable.
A common good answer is a reporting or search capability: high read volume, visible slowness in the legacy system, few writes, and a natural boundary. A common bad answer is core transaction posting, which is where every dependency converges — that one comes later, once the facade is proven and the team has extracted several capabilities successfully.
Sequencing after the first is mostly about following the data. Extract capabilities in an order that lets entity ownership move cleanly, so each step reduces synchronisation rather than adding to it.
When a full rewrite is genuinely right
Incremental is not universally correct, and pretending otherwise leads to elaborate facades around systems that deserved to be deleted.
- The system is small. If a competent team can rebuild it in a few months, the facade, the synchronisation and the dual running cost more than the thing they de-risk.
- The platform is dead. No supported runtime, no available skills, no way to build the integration points a facade requires. Sometimes you cannot get a foothold in the old system at all.
- Nobody is disrupted. An internal tool with a handful of users who can be trained in an afternoon does not need a staged transition.
- The data model is the thing being replaced. If every entity boundary changes, incremental extraction means permanent translation between two incompatible models, and the translation layer becomes the project.
- The old system is genuinely disposable. Low usage, low business value, well-understood behaviour, no undocumented edge cases worth preserving.
The honest test is whether you would accept the total-rewrite failure modes — knowledge locked in code, a moving target, no value until cutover — for this specific system. For a two-month internal tool, yes. For the system that takes the orders, no. Those failure modes are set out in more detail in our comparison of rewriting, refactoring and replatforming.
Knowing it is working
Progress on a strangler programme is not measured in features shipped. The useful indicators are subtractive:
- What proportion of production traffic no longer reaches the legacy system?
- How much legacy code has been deleted, not merely bypassed?
- How many entities still require synchronisation between the two systems?
- How much business logic sits in the facade, and is that number falling?
- What legacy infrastructure has actually been switched off?
If those numbers are not moving while delivery continues, the programme is adding a system rather than replacing one. That is worth catching in month four rather than year two, and for ERP estates the same measurement discipline applies — see our guide to modernising an ERP without stopping the business.
How we approach it
Our legacy application modernization engagements begin by mapping consumers and data ownership, because those two things determine the extraction order and everything else follows from it. The facade, the first extraction and the comparison harness are built by the same engineering team that will run the transition, with a decommissioning date agreed before the first line of replacement code is written.
Tell us what you are trying to replace and we will tell you honestly whether it should be staged or simply rebuilt.


