Strangler Figure Pattern Explained
Replacing a large, mission-critical legacy system with a modern architecture is one of the riskiest undertakings in software engineering. The "big bang" rewrite—where the old system is turned off and the new one turned on in a single event—has a long history of spectacular failures. The Strangler Fig Pattern offers a safer alternative: an incremental, evolutionary approach to modernization that keeps the existing system running while gradually replacing it piece by piece.
Named after the strangler fig tree, which grows around a host tree, eventually replacing it, this pattern allows teams to deliver value continuously, reduce risk, and maintain business operations throughout a multi-year migration.
What Is the Strangler Fig Pattern?
The Strangler Fig Pattern is an incremental migration strategy for modernizing legacy systems. Instead of rebuilding the entire system at once, teams build new functionality alongside the old, gradually redirect traffic to the new components, and retire legacy modules one at a time.
The core idea follows a consistent lifecycle:
- The existing system remains fully operational and continues to serve all requests.
- New functionality is built as separate services or modules, often using modern technologies.
- A routing layer intercepts requests and directs some to the new components.
- Over time, as the new implementation matures, more traffic is shifted away from the legacy system.
- Legacy modules are retired once no longer needed.
- The process repeats until the legacy system is completely replaced.
This evolutionary approach minimizes downtime, allows incremental validation, and gives the organization the ability to pivot or roll back at any stage.
Why Legacy Migration Is Difficult
Legacy systems often represent years or decades of accumulated business logic. Migration is difficult for several reasons:
- Large codebases – Millions of lines of code with deep, undocumented business rules.
- Tight coupling – Components are heavily interdependent; changing one part can break distant others.
- Limited documentation – Original developers may have left; knowledge resides only in the code.
- Shared databases – Multiple applications read and write the same tables, making extraction painful.
- Unknown business logic – Edge cases are baked into the system and only discovered when they break.
- High business risk – A failure in the migration can directly impact revenue, customers, and reputation.
- Downtime concerns – The business cannot afford to take the system offline for an extended cutover.
Complete rewrites frequently fail because they attempt to solve all these problems simultaneously, without the safety net of the existing working system. The Strangler Fig Pattern addresses this by never requiring a “switch” moment.
Core Principles
- Incremental Replacement – Modernization happens in small, manageable steps, each delivering value.
- Business Continuity – The legacy system remains in place; the business never stops operating.
- Progressive Routing – A gateway or proxy directs requests to the appropriate new or old implementation based on configurable rules.
- Independent Deployment – New components are deployed and validated independently, without risk to the legacy system.
- Continuous Validation – Each extracted service is tested and monitored in production before decommissioning the legacy equivalent.
- Low-Risk Migration – If a new service fails, traffic can be instantly routed back to the legacy system, reducing blast radius.
Typical Architecture
During a Strangler Fig migration, an architecture typically looks like this:
The Routing Layer (often implemented as part of an API Gateway or reverse proxy like NGINX) knows which paths or features have been migrated. Over time, routing rules are updated to send more traffic to the new services. The legacy system shrinks until it is empty and can be decommissioned.
Migration Process
A typical Strangler Fig migration proceeds through several phases.
Phase 1 — Legacy Monolith
All functionality resides in a single monolithic application. This is the starting state.
Phase 2 — Introduce Gateway
An API Gateway or reverse proxy is placed in front of the monolith. Initially, all traffic passes through to the legacy system unchanged.
Phase 3 — Extract Individual Modules
Teams extract functionality one bounded context at a time. The first extraction might be authentication. The Gateway is configured to route /auth/* to the new service.
Phase 4 — Redirect Traffic
As confidence in the new service grows, traffic is gradually shifted—perhaps using canary deployments: 10% to the new service, then 50%, then 100%.
Phase 5 — Remove Legacy Components
Once the new service handles all traffic for that capability, the corresponding legacy code, tables, and infrastructure are decommissioned.
Phase 6 — Complete Modernization
The process repeats for each module (Product Catalog, Orders, Payments, etc.) until the monolith is empty. The legacy system is shut down.
Migration Strategies
Several strategies can be applied depending on the nature of the system.
- Feature-by-feature migration – Each user-facing feature is extracted independently. This works well when features are loosely coupled.
- Domain-by-domain migration – Aligns with bounded contexts; entire business capabilities are moved to new services.
- API-first migration – The legacy system’s API is replicated by a new service, and consumers are gradually switched over.
- UI replacement – A new frontend consumes both legacy and new backend APIs, hiding the migration from end users.
- Database migration – Data is extracted along with the service; often involves change data capture or event synchronization.
- Event-driven migration – The legacy system publishes events as it processes commands; new services consume these events and take over responsibility.
Real-World Example: E-Commerce Platform Migration
An e-commerce company wants to modernize its monolithic platform. The monolith handles authentication, product catalog, shopping cart, orders, payments, inventory, and notifications.
Migration Step-by-Step
Step 1: Introduce API Gateway All client requests now go through an API Gateway. Initially, the gateway routes everything to the monolith.
Step 2: Extract Authentication
A new Auth Service is built with modern OAuth2/OIDC. The Gateway routes /auth/* to the new service. Existing sessions are migrated or allowed to expire naturally.
Step 3: Extract Orders
A new Order Service is built. The Gateway routes /orders/* to it. The Order Service may temporarily need to call legacy inventory or payment APIs until those are also extracted (anti-corruption layer pattern). Alternatively, it publishes an OrderCreated event that the legacy system consumes to update its state.
Step 4: Extract Inventory and Payments These services are extracted one by one. Communication between services transitions to events via a broker.
Step 5: Retire Legacy Components Once a service is fully migrated, the corresponding monolithic code and database tables are removed. Database references are cleaned up.
Step 6: Shutdown Monolith When all capabilities have been extracted, the monolith is decommissioned. The gateway becomes the frontend to a pure microservices ecosystem.
Database Migration
Databases are often the hardest part of a migration. Strategies include:
- Shared database (temporary) – The new service reads/writes its own tables in the existing database, then they are moved to a dedicated database later. This reduces risk but must be strictly timeboxed.
- Database per service – The new service gets its own database from the start. Data is synchronized using Change Data Capture (CDC) or dual writes.
- Event synchronization – The legacy system publishes events; the new service consumes them to build and maintain its own data copy.
- Dual writes – Both old and new systems are updated simultaneously. This is risky and should be avoided unless combined with compensating transactions or a reconciliation process.
- Data validation – During migration, both systems operate in parallel (shadow mode) to compare results and ensure correctness before cutover.
Best practice: extract data along bounded context lines, use CDC for initial sync, and cut over reads and writes in a controlled manner.
Advantages
- Lower migration risk – Each step is small, reversible, and independently validated.
- Continuous delivery – New features can be built in the new system even during migration.
- No major downtime – The system never switches off; users may not even notice the transition.
- Incremental modernization – Delivers value early and often; ROI is realized before migration completes.
- Easier rollback – If a new service has problems, routing flips back to the legacy service instantly.
- Progressive validation – Real traffic validates the new components progressively.
- Better business continuity – Operations continue unaffected.
Challenges
- Temporary architectural complexity – During the transition, the system has both old and new components, a routing layer, and possibly synchronization logic.
- Duplicate functionality – The same business capability may exist in two places for a time, requiring maintenance of both.
- Data synchronization – Keeping legacy and new databases consistent during migration is non-trivial.
- Routing complexity – Routing rules grow as more services are extracted; must be managed carefully.
- Monitoring both systems – Both legacy and new services must be monitored to detect anomalies.
- Longer migration timeline – Incremental migration can take months or years, requiring sustained organizational commitment.
These challenges are manageable but require deliberate engineering discipline and strong observability.
Relationship with Other Patterns
The Strangler Fig Pattern often relies on or complements several other architectural patterns.
| Pattern | Role in Migration |
|---|---|
| API Gateway | Central routing point, directing traffic to new or old services based on path, header, or feature flag. |
| Anti-Corruption Layer | Protects the new service's clean domain model from the legacy system's convoluted data formats. |
| Event-Driven Architecture | Enables decoupled data synchronization and eventual consistency during migration. |
| CQRS | Separate read and write models allow migrating reads and writes independently. |
| Saga Pattern | Manages distributed transactions that may span old and new systems temporarily. |
| Modular Monolith | If the legacy codebase is first refactored into clear modules, extraction becomes simpler. |
Strangler Fig vs Big Bang Rewrite
| Aspect | Strangler Fig | Big Bang Rewrite |
|---|---|---|
| Risk | Low; each step is reversible | Very high; failure means no fallback |
| Cost | Spread over time; value delivered early | Large upfront investment; ROI only at the end |
| Downtime | Minimal; no cutover event | Usually requires system outage |
| Business Continuity | Operations continue throughout | May be disrupted during switch |
| Validation | Progressive, with real traffic | Only fully validated at the end |
| Deployment | Continuous, incremental | Single, high-stakes deployment |
| Rollback | Easy; reroute traffic to old system | Difficult; may be impossible |
| Delivery Speed | Faster time-to-market for individual capabilities | Delayed until everything is rebuilt |
The incremental approach is generally preferred for all but the smallest, least critical systems.
Architecture Best Practices
- Start with low-risk services – Choose a simple, decoupled module as the first extraction target to build confidence and processes.
- Migrate by business capability – Use bounded contexts to define service boundaries; avoid slicing by technical layers.
- Introduce an API Gateway early – It becomes the control point for all routing decisions.
- Monitor every migration step – Track error rates, latency, and traffic splits for both new and legacy components.
- Automate testing – Comprehensive regression tests ensure that the new service behaves identically to the legacy one.
- Avoid permanent dual writes – If you must write to both systems temporarily, implement robust reconciliation and have a plan to eliminate it.
- Keep migration iterations small – A module should be extracted, validated, and legacy cleaned up in weeks, not months.
- Remove legacy code continuously – After successful extraction, delete the old code. Allowing it to linger creates confusion and maintenance debt.
Common Mistakes
- Attempting to migrate everything at once – Defeats the purpose; incremental means incremental.
- Ignoring domain boundaries – Extracting by technical layer (e.g., “the data layer”) instead of business capability leads to distributed spaghetti.
- Keeping duplicated logic indefinitely – The strangler should eventually kill the host; leaving old implementations around complicates the system.
- Sharing databases permanently – If both old and new systems share the same database, the service is not truly independent.
- Poor monitoring during migration – Without observability, subtle differences between old and new implementations cause production incidents.
- Delaying legacy system cleanup – Decommissioned modules should be physically removed, not just switched off.
Interview Perspective
System design interviews may include migration scenarios to test your architectural pragmatism. Common questions:
- What is the Strangler Fig Pattern, and why is it useful?
- Why is it better than a full rewrite?
- How does request routing work during migration?
- How do you migrate databases safely?
- What role does an API Gateway play in this pattern?
- How do you know when migration is complete?
- Walk me through how you would migrate a large monolith to microservices.
Demonstrate that you understand the business risk of big bang approaches and can articulate a practical, iterative strategy.
Summary
The Strangler Fig Pattern provides a safe, incremental path for modernizing legacy systems. By introducing a routing layer, extracting functionality piece by piece, and gradually decommissioning old components, organizations can transform their architecture without risking business continuity.
While it introduces temporary complexity, this pattern significantly lowers the risk of migration, enables continuous delivery, and allows teams to validate new services in production over time. For any enterprise embarking on a cloud migration or microservices transformation, the Strangler Fig is an essential tool in the architect's toolbox.