The Strangler Pattern
Date: 2026-08-17
Replacing a system by routing traffic away from it a piece at a time, while both run, until nothing reaches the old one. It’s the only replacement strategy that ships value before it finishes — which matters because the alternative, a parallel rewrite, has a well-documented habit of never finishing at all.
The strangler pattern (strangler fig) is incrementally replacing a legacy system by routing individual routes or features to a new system until the old one handles nothing and can be switched off.
The mechanism
A router — a reverse proxy, a CDN rule, a load balancer, an edge function — sits in front of both systems and decides per request.
┌─────────────┐
───────│ router │
└──┬───────┬──┘
│ │
/basket │ │ everything else
▼ ▼
┌────────┐ ┌──────────────┐
│ new │ │ legacy │
└────────┘ └──────────────┘
month 1 /basket → new 5% of traffic
month 3 /basket /checkout → new 20%
month 6 /basket /checkout /product/* → new 70%
month 9 everything except /account/* → new 95%
month 11 everything → new 100% legacy switched off
The routing rule is the whole design. It has to be expressible in something that sits in front of both systems and is cheap to change — usually a URL path prefix, sometimes a hostname, occasionally a cookie or a header for internal testing. If the boundary can’t be stated as a routing rule, this pattern doesn’t apply directly and the seam has to be created first.
The name is Martin Fowler’s, after strangler fig trees, which grow around a host tree until it dies and rots away leaving the fig standing.
Why it beats a rewrite
| Big-bang rewrite | Strangler | |
|---|---|---|
| First value delivered | At the end, if ever | Weeks in |
| Feature freeze on the old system | Yes, for the duration | No |
| Risk profile | One enormous cutover | Many small reversible ones |
| Rollback | A project | A routing change |
| Discovers requirements | At acceptance testing | Continuously, per slice |
| Failure mode | Cancelled after 18 months, nothing shipped | Stops partway — and you keep what shipped |
The last row is the strongest argument. A strangler migration that runs out of budget halfway leaves a working hybrid; a rewrite that runs out of budget halfway leaves nothing. Given how often the budget does run out, optimising for a survivable partial outcome is the realistic choice, not the pessimistic one.
What makes it hard
- Two systems, one database. The usual arrangement, and it means both must agree on schema. Expand-contract applies throughout — Database Migrations
- Shared session and identity. A customer crossing from legacy to new mid-journey must stay logged in and keep their basket. Solving this is usually the first slice, before any user-facing work — Sessions and Tokens
- Duplicated logic during the overlap. Pricing rules, tax and promotions exist in both. Either extract them behind a service both call, or accept a period where the two must be kept in sync by hand and tested against each other
- You are paying for both. Two systems, two sets of infrastructure, two on-call rotations, for a year
- The last 5% takes as long as the first 50%. What’s left at the end is the weird admin screen nobody understands, used monthly by one department. It is still blocking decommission
The rules that keep it honest
- Slice by user journey, not by technical layer. “Checkout” is a slice; “the data access layer” is a rewrite in disguise with no shippable increment
- Start with something visible and low-risk. It proves the routing, the session sharing and the deploy path against real traffic while the stakes are low
- Never let the new system call back into the legacy one. Traffic flows one way through the router. A new service reaching into legacy internals recreates the coupling and makes decommission impossible
- Set a decommission date for each slice and hold it. Legacy code left switched on stays switched on, and “we’ll turn it off later” is how you end up permanently running both — Deprecation
- Track a single number: percentage of traffic on the new system. It’s the only progress metric that can’t be argued with, and it makes stalling visible in a way a Gantt chart doesn’t
- Keep the seam. The router you built is worth keeping afterwards — it’s what makes the next replacement cheap
Where it interacts
- Replatforming — the commerce-specific case, where the strangler is close to mandatory because a big-bang commerce cutover risks the entire revenue line
- Monolith vs Services — the correct way to extract a service, one route at a time
- Site Migrations and SEO — while both systems are live, URLs, canonicals and redirects must be coherent across the router, and crawlers must never see two versions of one page — Canonicalisation
- Feature Flags — a finer-grained version of the same routing decision, when the split is per-user rather than per-URL
- Progressive Delivery — ramping a slice from 5% to 100% rather than switching it, which is how you find the problems at low cost