# Strangler Fig Pattern: How to Replace a Live System

> How the strangler fig pattern replaces a live system piece by piece: put a switch in front, move slices in a safe order, handle data, and know when not to use it.

- Author: Filipe Eduardo, Senior Software Engineer (https://filipeeduardo.dev/)
- Published: October 6, 2026 · Updated: October 7, 2026
- Topic: Legacy modernization · Tags: strangler fig pattern
- Canonical URL: https://filipeeduardo.dev/blog/strangler-fig-pattern

![Illustration of an old server tower wrapped by growing cables, with an orange track switch routing traffic to new modules](https://cms.filipeeduardo.dev/wp-content/uploads/2026/10/strangler-fig-pattern-1.webp)

## Key takeaways

- Put a switch in front of everything before you write any new code. That switch is what makes the rest safe.
- Move one slice of behavior at a time. Keep the old path alive until the new one has proven itself with real traffic.
- Start with low-risk, well-understood pieces. Leave the money paths and the tangled core for when your process is proven.
- In my experience, data is the hardest part. Plan how the old and new systems share or sync it before you move the first slice.
- The pattern costs you a period of running two systems. If the old system is small or already failing badly, a rewrite or a replatform may be cheaper.

The **strangler fig pattern** is a way to replace a live system gradually. You put a routing layer in front of the old system and build new pieces behind it one at a time. When each new piece is ready, you send traffic to it, and you retire the old code as it goes unused. The product never stops, and there is no single launch day.

I used this approach when I led the [full migration of a platform](https://filipeeduardo.dev/blog/migrating-a-live-platform-to-a-new-stack) that applies to job openings automatically for its users. Its whole architecture moved from a legacy stack to a new one while people kept using it every day. This article explains how the pattern works, in the order I would apply it, and where it does not fit.

## What is the strangler fig pattern, and where does the name come from?

The name comes from strangler figs, rainforest plants that grow around a host tree. Over years, the fig builds its own structure around the tree until the original tree is gone and the fig stands on its own. Martin Fowler borrowed the image in the early 2000s to describe migrating software the same way: grow the new system around the old one until the old one can be removed.

The contrast is the big-bang rewrite. In a rewrite, a team builds the replacement in parallel, usually for months, then cuts over on one date. Everything has to match the old behavior on that day, including the behavior nobody documented. Rewrites tend to cost more and take longer than incremental migration, because the old system must keep running and changing while the new one is being built.

With the strangler approach, you keep the product running and move it piece by piece. Each piece is small enough to test, release and roll back on its own.

## How does the switch in front of the old system work?

The switch is a routing layer that sits between users and your systems. Every request goes through it. Its first version does nothing clever: it forwards 100% of traffic to the old system. That is the point. You are proving the layer is safe before it carries any risk.

This is where I start, both on the job-application platform migration and on any live system I take over. Before the switch exists, every change is a bet. After it exists, every change can be undone.

### What the switch needs to do

-   **Route by path or capability.** For example, requests to one URL prefix or one API endpoint go to the new service, and everything else goes to the old one.
-   **Route by audience.** Send internal users first, then a small share of real users, then everyone. This is where [feature flags and canary-style rollouts](https://filipeeduardo.dev/blog/feature-flags) come in.
-   **Switch back instantly.** Rollback should be a configuration change, not a deployment.
-   **Be observable.** You need to see errors, latency and outcomes per route, split by old versus new.

### What it can be

It depends on your system:

-   A reverse proxy or load balancer works for web apps.
-   An API gateway works for service-based backends.
-   In a frontend-heavy product, the switch can live in the app itself, with flags deciding which implementation renders.

Pick the simplest thing your team already knows how to operate. The pattern does not depend on a specific tool.

## What does a real strangler fig migration look like step by step?

This is the sequence I follow. The exact timing varies by system, so I will not put dates on it.

1.  **Get access and understand what exists.** This means repositories, hosting, databases, DNS and third-party accounts. You cannot route traffic you cannot control.
2.  **Map the system into slices.** List the user-facing capabilities and the background jobs. Each slice should have a clear input and output, for example "login", "search" or "send notification".
3.  **Install the switch, sending everything to the old system.** Release it alone. If something breaks, you know it is the layer and nothing else.
4.  **Add tests around current behavior.** Before replacing a slice, capture what it does today, including its quirks. These tests define "done".
5.  **Build the first slice in the new stack.** Keep it small and low-risk.
6.  **Run it in the shadows if you can.** Send copies of real requests to the new code and compare its answers to the old one. Do not show users the result yet.
7.  **Roll out gradually.** Start with internal users, then a small share, then more. Watch the metrics at each step and keep the rollback ready.
8.  **Retire the old slice.** Once it receives no traffic for a sensible period, delete the code. Skipping this step leaves you running two systems forever.
9.  **Repeat.** Each cycle makes the next one easier, because the switch, tests and monitoring already exist.

The data question runs through all of these steps, and it is where I have seen migrations get hardest. Either both systems read and write the same database for a while, or you sync data between them with something like [change data capture](https://filipeeduardo.dev/blog/change-data-capture). Decide this early, because it shapes how you slice the system.

## Which parts should you move first, and which last?

Order matters more than speed. The early slices teach your team how the old system really behaves, so they should be forgiving. When I take over a codebase, I follow a fixed order: access first, then the build, then the money paths, then the risks. The migration order below follows the same logic.

Move early

Move late

Read-only pages and endpoints

Payments, checkout and billing

Features with few dependencies

Core logic that every other feature calls

Parts with good test coverage or clear specs

Code nobody on the team understands yet

Slices that are painful to maintain today

Shared database tables with many writers

### Why money paths come later

Some code charges a customer or triggers an action that cannot be undone. That code deserves your most mature process. By then you have a working switch, comparison tests, dashboards and a rehearsed rollback. Moving it first means learning the pattern on your riskiest code.

There is a counterweight. If the old system’s biggest problem sits in the core, leaving it to the end can mean the migration never pays off. In that case, I start with the pieces around the core. They shrink it and clarify its edges, and then I tackle the core with the best tooling in place.

## When is the strangler fig pattern the wrong choice?

It is a strong default, but not universal. If a system falls into one of these cases, I would rather say so up front than force the pattern onto it:

-   **There is no seam to put a switch on.** Some desktop apps, embedded systems or tightly coupled monoliths do not route requests through anything you can intercept. You may need to create a seam first, which is its own project.
-   **The system is small.** If the whole thing can be rebuilt and verified in a short period, running two systems in parallel adds more overhead than it saves.
-   **The old platform is being shut down anyway.** If the vendor is ending support on a hard date, you may need a faster, more direct path.
-   **Old and new need incompatible data models.** If keeping the data in sync is harder than the migration itself, a planned cutover with a maintenance window can be the saner option.
-   **The team cannot sustain two systems.** The pattern means maintaining both for a while. If the team is already stretched thin, the transition period can hurt.

Also note what the pattern does not fix. If the product itself is wrong, a clean migration just gives you the same product on a newer stack.

## How does it fit into a wider legacy modernization plan?

The strangler fig pattern is a delivery method, not a strategy. Before choosing it, you should know three things: [why you are modernizing](https://filipeeduardo.dev/blog/legacy-modernization), what the current system does, and what you are willing to leave behind. A code audit and a look at your technical debt come first. Decisions about replatforming, [refactoring in place](https://filipeeduardo.dev/blog/legacy-code-refactoring) or replacing come next.

Around the migration itself, a few supporting practices do most of the work:

-   **Feature flags** for controlling who sees the new path.
-   **Canary or blue-green releases** for lowering the risk of each rollout.
-   **[A database migration plan](https://filipeeduardo.dev/blog/database-migration)** that covers sync, validation and cutover of data.
-   **Monitoring** that compares old and new behavior with real numbers.

The rule I carry from the job-application platform migration is simple: put the switch in front of everything before writing new code. Once users are flowing through a layer you control, every later decision becomes smaller and reversible.

## Planning a migration of your own?

If you are weighing this pattern for a live system, email me@filipeeduardo.dev with a short description of the stack and where it hurts. I’m glad to compare notes and tell you what I’d check first.

## Frequently asked questions

### Is the strangler fig pattern the same as a rewrite?

No. A rewrite replaces the system in one go. The strangler fig pattern replaces it in slices while the old system keeps serving users. You still write new code, but you release it incrementally.

### How long does a strangler fig migration take?

It depends on the size and tangle of the system, so any number I gave would be invented. What I can say is that the first slice should reach production quickly. That proves the switch, the tests and the rollback work.

### Do I need microservices to use it?

No. The new pieces can live in a new monolith, a modular app or separate services. The pattern only requires that you can route traffic between old and new.

### What is the biggest risk?

Two risks come up most often: Data that drifts out of sync between the systems. Never retiring the old code, which leaves you paying for both. Plan for data and deletion from the start.

### Can I use it for a frontend migration?

Yes. Route by page or component, using a proxy or feature flags, and move screens one at a time. Shared styles and state are the usual trouble spots.
