Strangler Fig Pattern: How to Migrate a Monolith Incrementally
How to apply the strangler fig pattern to migrate a monolith incrementally: route, replace, and retire without big-bang rewrites or downtime.
In this article:
- What the Strangler Fig Pattern Is
- The Three Phases: Seam, Route, Replace
- Applying Strangler Fig to Microservices Migration
- Common Mistakes and How to Avoid Them
- Conclusion
The strangler fig pattern is a migration strategy that replaces a legacy system incrementally by routing requests through a facade layer. New functionality is built in a new system. As each capability is reimplemented, traffic for that capability is routed from the legacy system to the new one. Over time, the new system handles more and more traffic, while the legacy system handles less and less, until it can be retired.
The name comes from the strangler fig tree, which grows around a host tree and eventually replaces it. The legacy system continues to function throughout the migration. Users notice no disruption. Engineers ship features to the new system throughout the migration rather than freezing development to complete a big-bang rewrite.
What the Strangler Fig Pattern Is
The strangler fig pattern was described by Martin Fowler as the standard approach for replacing legacy systems that cannot be taken offline for a full rewrite. It differs from a direct rewrite in three ways.
First, it produces a working system at every step. At any point during the migration, the combination of old and new is a functional, deployable system. There is no period where neither the old nor the new system is fully functional.
Second, it is reversible. Traffic routing between old and new is controlled by a layer (a proxy, a gateway, a feature flag) that can be reversed quickly. If the new implementation of a capability has a bug, routing flips back to the old system without a deployment.
Third, it delivers value throughout the migration. Because the new system is in production from an early stage, it can be improved, extended, and monitored. Teams do not wait six months to see whether the rewrite was successful.
The strangler fig pattern is particularly relevant for monolith decomposition projects where the goal is extracting services from a legacy codebase while maintaining production availability.
The Three Phases: Seam, Route, Replace
Phase 1: Identify the seam. A seam is a boundary in the legacy system where new behavior can be introduced without modifying existing code. In a web application, the most common seam is the HTTP routing layer: requests arrive, the router decides which handler processes them.
Introduce a facade or proxy in front of the legacy system. Initially, the proxy passes all requests through to the legacy system unchanged. This is a zero-risk deployment that establishes the routing infrastructure you will use throughout the migration.
Phase 2: Route selectively. Choose the first capability to migrate. Typical candidates are: functionality that is being actively changed (high development friction), functionality that needs to scale differently from the rest of the system, or functionality that is well-understood and low-risk to reimplement.
Implement the capability in the new system. When it is production-ready, update the proxy to route requests for that capability to the new system. The legacy system still handles everything else.
At this point, run both systems simultaneously for the migrated capability if you need confidence in the new implementation. The proxy can call both, compare outputs, and serve the legacy result until discrepancies are resolved. This is the parallel run pattern described in the branch by abstraction guide.
Phase 3: Replace and retire. Continue migrating capabilities one at a time. With each migration, the legacy system handles less traffic. Once all capabilities have been migrated and the legacy system receives zero traffic, retire it.
The retirement step is often underestimated. Legacy systems accumulate hidden dependencies: batch jobs, internal tools, one-off scripts, and direct database access by other systems. Before retiring the legacy system, audit all its incoming connections and ensure each one has been migrated or decommissioned.
Applying Strangler Fig to Microservices Migration
When the goal is moving from a monolith to microservices, the strangler fig pattern provides the migration path. The proxy becomes an API gateway. Each extracted service handles a specific subdomain of the business logic. The monolith shrinks as services are extracted.
The key decisions in a strangler fig microservices migration:
What to extract first. Extracting the highest-traffic capability first maximizes the operational benefit of the new architecture early. Extracting the most independent capability first minimizes risk. These are often different things. For a first extraction, favor the most independent capability: one that has minimal shared state with the rest of the monolith and well-defined boundaries.
Data migration. When a capability is extracted to a new service, the service needs its own data store. The data migration strategy is the most complex part of any monolith decomposition. Options include: sharing the monolith’s database temporarily, replicating data to a new store with synchronization during transition, or running both stores in parallel until the service is fully independent.
Transaction boundaries. Distributed transactions across services are expensive and fragile. Before extracting a capability, identify whether it participates in transactions with other capabilities that will remain in the monolith. If it does, either extract them together or redesign the boundary to avoid cross-service transactions.
Common Mistakes and How to Avoid Them
Extracting too much too fast. The strangler fig pattern works because each extraction is small and reversible. Teams that try to extract three services simultaneously lose the incremental safety properties. Extract one capability at a time.
Not investing in the proxy layer. The proxy is the operational center of the strangler fig migration. It needs monitoring, logging, circuit breakers, and the ability to route traffic with fine granularity. A thin reverse proxy without these capabilities will create operational problems as the migration progresses.
Migrating the monolith’s complexity into the new services. The purpose of the migration is not just to run the same code in a new deployment model. If a capability in the monolith has a cyclomatic complexity of 80 and no tests, extracting it to a microservice produces a microservice with a cyclomatic complexity of 80 and no tests. The extraction and the cleanup need to happen together.
No clear retirement plan. Without a committed plan to retire the legacy system, the strangler fig migration tends to stall. The legacy system ends up handling a long tail of edge cases and rarely-used functionality that is deprioritized indefinitely. Define retirement criteria at the start of the migration: what percentage of traffic reduction constitutes “ready to retire,” and what is the deadline.
Conclusion
The strangler fig pattern is the standard approach for replacing a legacy monolith incrementally. It delivers value throughout the migration, maintains production availability, and keeps the option to reverse course at every step. The three phases are simple: install a proxy, route capabilities one at a time, retire the legacy system when it handles zero traffic.
The complexity is in execution: data migration, transaction boundaries, and the discipline to extract incrementally rather than attempting big-bang decomposition. Teams that execute this discipline consistently complete migrations that would have taken 18 months as big-bang rewrites in 6 to 8 months of incremental delivery.
Does your codebase have these problems? Let’s talk about your system