Strangler Fig Pattern
The strangler fig pattern is a migration strategy that incrementally replaces components of a legacy system with new services, routing traffic gradually from the old system to the new one until the legacy system can be decommissioned.
What It Really Means
The pattern is named after the strangler fig tree, which grows around an existing tree, eventually replacing it entirely while the host tree decays. In software, you build new functionality alongside the old system, redirect traffic piece by piece, and eventually remove the old system — without a big-bang rewrite.
Big-bang rewrites fail. They take years, the requirements change while you are rewriting, the old system keeps evolving in parallel, and when you finally launch, you discover edge cases the old system handled that nobody documented. The strangler fig pattern avoids this by delivering incremental value. Each extracted component goes to production independently, gets validated with real traffic, and proves its correctness before you move on to the next.
Martin Fowler popularized the term in 2004, but the approach is ancient. Any time you have replaced one part of a system while keeping the rest running, you have used a variant of this pattern. What makes it a formal pattern is the deliberate routing infrastructure that lets you switch traffic between old and new implementations.
How It Works in Practice
The Three Phases
Phase 1: Identify and Extract
Choose a slice of functionality to extract. Start with something that has clear boundaries, low coupling to the rest of the system, and high business value. Often this is a read-only API or a self-contained feature.
Phase 2: Build and Route
Build the new service that implements the same functionality. Deploy it alongside the old system. Set up a routing layer (reverse proxy, API gateway, or load balancer) that can direct traffic to either the old or new implementation based on configuration.
Phase 3: Validate and Migrate
Start routing a small percentage of traffic to the new service. Compare responses. When confidence is high, route 100% of traffic to the new service. Decommission the corresponding code in the old system.
Repeat for the next slice.
Real-World Example: Shopify's Checkout Migration
Shopify migrated their checkout system from a monolithic Rails app to a new architecture. Instead of rewriting checkout entirely:
- They identified checkout as a bounded context with clear inputs and outputs
- Built a new checkout service behind a feature flag
- Routed a small percentage of checkouts to the new service, comparing outcomes
- Gradually increased traffic as confidence grew
- Eventually retired the old checkout code from the monolith
At no point was checkout unavailable. Merchants experienced no downtime. If the new service had issues, traffic was instantly routed back to the old system.
Routing Strategies
Path-based routing: The API gateway routes /api/v2/orders/* to the new service and everything else to the monolith.*
Header-based routing: Requests with X-Use-New-Service: true go to the new service. Useful for internal testing before public rollout.
Percentage-based routing: 10% of requests go to the new service, 90% to the old. Gradually increase as you gain confidence.
User-based routing: Specific user segments (internal employees, beta users) use the new service. Everyone else uses the old system.
Implementation