The strangler fig pattern lets you replace a legacy application in small, reversible steps: place a routing layer in front of it, build new implementations for bounded capabilities, and shift traffic to them as they are ready. The legacy system continues handling everything that has not moved. Retire it only after its functionality, data responsibilities, and callers have been accounted for.
How the strangler fig pattern works
A façade, proxy, API gateway, or equivalent routing layer sits between clients and the application. At first, it sends requests to the legacy implementation. As replacement capabilities become ready, the routing layer directs selected requests to the new implementation instead. Clients can keep using the same entry point while the system behind it changes.
As an Amazon Associate I earn from qualifying purchases.
The legacy path remains available during coexistence, giving the team a way to redirect traffic back if a replacement is not behaving as expected. Once a capability has moved and its dependencies are clear, the corresponding legacy functionality can be removed. Microsoft describes eventually removing the façade and reconfiguring clients to call the new system directly; keeping the façade as a deliberate compatibility adapter is another option.
Free tools Windows power users keep installed
One-click scans. No signup required.
AWS summarizes its monolith-modernization sequence as transform, coexist, eliminate: build replacement components, operate old and new paths together while selected calls are redirected, then retire the replaced functionality.
#1 Best Overall
A practical migration sequence
1. Choose a seam and define what is moving
Start with a capability that has a clear boundary: its behavior can be described, tested independently, and routed explicitly. Map the relevant callers, data, and dependencies before extracting it. Smaller components make each introduction less risky and give the team a chance to learn before choosing the next boundary. Martin Fowler’s guidance on the pattern emphasizes creating seams that isolate components rather than attempting to replace an entire system at once.
Write down what counts as “moved” for this capability: the functions it must support, which system owns its data during the transition, and what evidence will be needed before the old implementation is retired.
2. Put request routing in place
Introduce a façade, proxy, API gateway, or other routing layer that can intercept the requests in scope. Initially, route them to the legacy application. Confirm that you can identify and direct the relevant traffic before relying on the layer for a migration; without interceptable requests, the pattern cannot control the transition.
Because this layer sits on the request path, include its capacity and resilience in the design. A failure or bottleneck there can affect both old and new functionality. Decide how it will be monitored and how routing changes can be reversed.
3. Build the replacement alongside the old path
Implement one bounded capability without removing its legacy counterpart. Keep the client-facing entry point stable where possible, and use an adapter or anti-corruption layer when the new component needs to communicate with legacy interfaces. Such a layer can translate between the two models and help keep legacy conventions from spreading into the replacement.
Validate the replacement against the behavior expected at that boundary before sending it production traffic. The old implementation remains the active route until the new one is ready for a controlled shift.
4. Shift traffic in controlled increments
Change the routing for a capability only when its replacement is ready and the team can observe its behavior. Choose the size and pace of each shift to match the system’s risk and monitoring. Define in advance what evidence would cause the team to pause or send traffic back to the legacy path; AWS recommends having a rollback plan for each refactored service.
Do these 3 things before closing this tab:
1Fix the driver behind crashes, sound loss and screen glitches2Clear out junk files and repair common Windows errors3Scan for outdated or missing drivers - takes under a minuteTraffic can move in phases rather than through one all-at-once cutover. AWS’s 2026 API-decomposition example uses staged traffic movement and canary deployment. It is an AWS-specific implementation example, not a requirement to use those services or that deployment method.
5. Set rules for data ownership and synchronization
Routing requests gradually does not, by itself, make data migration safe. Decide which system owns each data domain while both systems are active, how downstream consumers will receive updates, and what consistency delay they can tolerate.
Rank #4
For a database domain being extracted, plan the initial copy, ongoing change capture, validation, cutover, and rollback before removing legacy data. Microsoft describes staging an ETL copy and change-data-capture synchronization, then validating the data before the new service writes to its own domain database. AWS also describes event-based synchronization that leaves a legacy database eventually consistent. If using asynchronous synchronization, make the expected delay explicit and decide how discrepancies will be detected and corrected.
6. Retire the old path only after checks
Before removing a legacy implementation, establish that the required functionality has moved, the relevant data has been validated, and remaining callers no longer depend on it. Account for downstream consumers as well as direct clients. Keep the rollback option until the team has enough evidence to accept the new path without it.
Recommended Free Tools
After the legacy application is retired, remove the façade if clients can safely call the new system directly. Retain it only when it still serves a deliberate compatibility or routing purpose; it has ongoing operating and reliability costs either way.
Best Value
When to use this pattern—and when to consider another
The strangler fig pattern is most useful when replacing a large or complex system all at once would create material risk, the functionality can be divided into boundaries, and requests can be intercepted. It is a poor fit for a small, low-complexity system where the routing layer and parallel operation add more burden than value, or when the relevant requests cannot be intercepted.
For a component buried inside the monolith with upstream callers that are difficult to route through an external façade, AWS recommends considering branch by abstraction instead. In that approach, introduce an internal abstraction, move callers to it, put the replacement behind it, and switch implementations when the replacement is ready.
| Decision factor | Strangler fig | Branch by abstraction |
|---|---|---|
| Where the boundary sits | Works well when a capability can be reached through requests intercepted by a façade or proxy. | Can suit a deeply embedded component whose callers are inside the monolith. |
| How callers are redirected | The routing layer sends selected requests to the legacy or replacement implementation. | Callers are moved to an internal abstraction, which can select the implementation. |
| Key prerequisite | Relevant requests must be interceptable and routable. | Callers must be able to move to the abstraction before the implementation is switched. |
| Source basis | AWS and Microsoft pattern guidance. | AWS modernization guidance. |
Risks to include in the migration plan
- Rollback: Keep the legacy route available while the replacement is being validated, and define how a routing change will be reversed.
- Boundary quality: A poorly isolated capability can leave hidden dependencies that make extraction and retirement harder.
- Data ownership: Shared access or synchronization between old and new components needs explicit rules; asynchronous updates can mean consumers see temporarily stale data.
- Transition cost: Both implementations, the routing layer, and synchronization processes may need to run at once. AWS’s API example notes that old and new endpoints remain operational during traffic shifting, increasing resource costs.
- Routing reliability: The façade becomes part of the request path, so plan for its capacity and resilience rather than treating it as a temporary, cost-free switch.
- Organizational readiness: Fowler notes that modernization also requires changes to development practice, organization, and business collaboration; otherwise, a new system can reproduce the old system’s problems.
Fowler’s assessment captures the tradeoff: “While this may appear to be a waste, the reduced risk and earlier value from the gradual approach outweigh its costs.” — Martin Fowler, “Strangler Fig,” 2024-08-22.
Cloud implementation examples are optional
The pattern is an architectural approach, not a requirement to adopt a particular cloud provider or routing product. AWS describes proxy-based routing between a monolith and services, and its 2026 API example uses CloudFront, CloudFront Functions, and KeyValueStore for staged traffic movement. Those are AWS-specific examples; choose implementation components based on the system’s actual routing and operational needs.
AWS guidance states that Migration Hub Refactor Spaces has not been open to new customers since 2025-11-07 and points to AWS Transform for similar capabilities. Product availability can change, so verify the current status with AWS before basing a migration plan on either service.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.




