In a rainforest, a strangler fig starts as a seed in the branches of a host tree. It grows roots downward and a lattice around the trunk, slowly taking over the host's structure. Years later the original tree has rotted away — and the fig stands exactly where it was, fully formed.
That's the perfect metaphor for replacing a legacy system. Instead of rewriting everything at once and flipping a switch, you grow the new system around the old one, moving over one piece at a time. The Strangler Fig pattern turns a high-risk rewrite into a long series of small, safe steps.
The problem
Big-bang rewrites are where ambitious projects go to die. You spend months or years building a replacement while the old system keeps changing underneath you. On launch day you cut over everything at once — and discover all the undocumented behavior, edge cases, and integrations the old system quietly handled. The blast radius is the entire product.
Meanwhile, you can't just stop and rebuild; the business needs the current system running the whole time. What you want is a way to modernize incrementally — perhaps peeling a monolith apart into microservices — while keeping the lights on and being able to back out of any single step that goes wrong.
- Legacy monolithOne large application handling every feature at once. Any change risks the whole thing, and there's no safe way to replace just a part of it.
- Shared databaseAll features read and write the same store, so the data is as tangled as the code — a big-bang rewrite has to untangle both at once.
How it works
You place a facade — often an API gateway or routing proxy — between callers and the system. At first, the facade simply forwards every request to the legacy application; nothing changes for the caller. Then you build the first replacement feature as new code and update the facade's routing: requests for that one feature now go to the new service, everything else still goes to the old one.
You repeat, feature by feature. Each step the new system grows and the legacy shrinks, while the facade hides the seam so consumers never know a migration is underway. The new code is free to use modern structure like a clean architecture without being dragged down by the old design. Eventually the legacy system handles nothing, and you delete it. The diagram below shows the facade routing some paths to the legacy monolith and others to the new service.
- FacadeSits in front and routes each request by path — migrated features to the new service, everything else still to the legacy system.
- Legacy monolithThe old system, kept running and slowly shrinking as features move off it until it can be switched off.
- New serviceModern replacement built one feature at a time; the facade hides the seam so callers never notice the migration.
Plan how the two sides share data. While both systems run, they often need the same data, and that's the trickiest part. You may need the new service to read the old database, sync changes between them, or route reads and writes carefully so neither side sees stale data. Decide this early — it's far more likely to bite you than the routing itself.
When to use it
Use the Strangler Fig whenever you're modernizing a system that's too important to take offline and too large to rewrite safely in one go — the classic monolith-to-services migration, or moving a creaky on-prem app to the cloud. Its great virtue is that you ship value continuously and can pause, reverse, or reprioritize at any point.
It's overkill for small systems where a clean rewrite is genuinely a weekend's work — the facade and dual-running overhead would cost more than they save. And it demands discipline: a half-finished migration that stalls leaves you maintaining two systems indefinitely. Commit to actually finishing the strangling, and the old tree really does come down.