What Is the Strangler Fig Pattern?
The strangler fig pattern replaces a legacy system incrementally by routing traffic to new services piece by piece, until nothing old remains.
The strangler fig pattern is a migration strategy for replacing a legacy system incrementally: new functionality is built alongside the old system, a routing layer directs traffic to the new code piece by piece, and the legacy system is retired once nothing depends on it anymore. Nobody flips a switch and cuts over all at once — the old system keeps running the whole time, doing a little less work with each release, until eventually it does none.
Where the name comes from
The pattern is named for the strangler fig plant, which germinates in the canopy of a host tree and sends roots down to the ground over years, gradually enveloping the host’s trunk. Eventually the host tree dies and rots away, leaving the fig standing in a shape that still traces the tree it grew around. Martin Fowler coined the software analogy: the new system grows around the old one, taking over its structure a piece at a time, until the original can be removed without the whole thing collapsing.
How the migration actually works
The mechanics come down to three ongoing pieces, running in parallel rather than in strict sequence:
- A routing layer (the facade). Something — an API gateway, a reverse proxy, or an application-level router — sits in front of both the old and new systems and decides, per request, which one handles it. This facade is what makes incremental migration possible at all: without it, you’re back to an all-or-nothing cutover.
- New functionality built against the new system. Each migrated capability is implemented fresh — not ported line-for-line — against whatever target architecture you’re moving to, whether that’s a set of services behind a service mesh or a simpler modular monolith.
- Traffic shifted incrementally, often behind a feature flag so a given slice of routes, tenants, or request types can be moved to the new implementation and rolled back instantly if something breaks, without touching a deploy.
Data is usually the hardest part in practice. If both systems need to read consistent state during the transition, that typically means either the new system reads from the old system’s database directly for a while, or a synchronization mechanism keeps both copies current — the same class of problem covered in database migrations and, for systems that need to keep a full history of state changes rather than just the current snapshot, event sourcing.
Strangler fig vs a big-bang rewrite
| Strangler fig | Big-bang rewrite | |
|---|---|---|
| Cutover | Gradual, piece by piece | All at once |
| Risk exposure | Small, per-slice | Concentrated in one release |
| Rollback | Revert one route or flag | Revert the entire system |
| Old and new run in parallel | Yes, throughout the migration | No — usually a hard cutover |
| Time to any user-visible value | Sooner — first migrated slice ships early | Only at the very end |
| Operational overhead during migration | Higher — two systems to run and monitor | Lower — one system at a time |
The trade a team is making is upfront simplicity against risk: a big-bang rewrite is conceptually cleaner and doesn’t require running two systems side by side, but it means the business is betting on a single release date, often months or years out, with no partial credit if something’s wrong. The strangler fig pattern accepts sustained operational complexity — dual systems, a routing layer to maintain, careful attention to idempotency so retried requests don’t get processed by both systems — in exchange for a migration where each step is small enough to verify and reverse independently.
When it’s the wrong tool
The pattern assumes the legacy system is decomposable — that you can carve off one capability, one route, or one tenant at a time without every piece being tightly coupled to every other piece. A tightly coupled monolith with a single shared, non-partitionable data model can make that decomposition harder than the migration itself, and it’s not unusual for the initial work of finding those seams to take longer than the actual migration that follows. The pattern also has an ongoing cost while it’s in progress: two systems in production means two things to monitor, patch, and reason about, so a migration with no clear end date can leave a team stuck paying that cost indefinitely rather than realizing it.
The takeaway
The strangler fig pattern replaces a legacy system by building new functionality alongside it, routing an increasing share of traffic to the new code through a facade layer, and decommissioning the old system only once nothing depends on it. It trades the operational overhead of running two systems in parallel for a migration where each step can be shipped, verified, and rolled back independently — a better fit for large or high-stakes systems than a single big-bang cutover, provided the legacy system can actually be carved into independent pieces in the first place.
Keep reading
Chisato · · 4 min read Event Sourcing Explained: Store Changes, Not State
Event sourcing stores every state change as an immutable event instead of overwriting current state. How it works, and when CQRS pairs with it.
The Lycoris Team · · 5 min read What Is a Distributed Lock?
A distributed lock coordinates exclusive access to a shared resource across multiple processes or machines, preventing race conditions in distributed systems.
Chisato · · 4 min read Token Bucket vs Leaky Bucket Rate Limiting
Token bucket allows bursts up to a cap; leaky bucket smooths traffic to a constant rate. How each rate-limiting algorithm works and when to pick it.