CMD Guide
HomeSystem DesignMicroservices Patterns

Introduction

The Strangler Fig Pattern replaces a legacy system incrementally by inserting an interception layer (a reverse proxy or API facade) in front of it and re-pointing one capability's route at a time to a new service, so the monolith's share of live traffic shrinks toward zero without a single big-bang cutover.

The name comes from the strangler fig tree, which germinates high on a host tree, sends roots down around the trunk, and slowly envelops it until the original tree dies and rots away, leaving a self-supporting fig in its exact shape. That is the whole strategy in one image: you grow the new system around the old one, feeding on its traffic, until the old one can be safely removed. The mechanism that makes this possible in software is not the tree — it is the facade in front that can send each request to either backend.

diagram
diagram

How the facade routes one request

The facade is the only thing clients talk to; it holds a routing table and forwards each request to whichever backend currently owns that path. Trace two live requests during the migration above:

  1. GET /orders/history?userId=8821 arrives at the facade.
  2. The facade matches the longest-prefix rule /orders/history and its target is order-history-svc (new-service weight = 100%).
  3. It forwards the request; the new service queries the orders table and returns 200 in ~180 ms.
  4. Moments later GET /cart/8821 arrives. No new-service rule matches, so the facade falls through to its default target — the monolith — which answers as it always has.
  5. The client saw a single hostname and never knew two different systems answered. That indistinguishability is exactly what lets you move routes one at a time.

A worked migration, week by week

Concrete scenario: an e-commerce monolith serving /orders, /cart, /payments, and /catalog. We strangle the single endpoint GET /orders/history first. The whole point is that every phase is a config change at the facade, reversible in seconds.

PhaseFacade rule for /orders/historyTraffic to new svcWhat you verify before proceeding
Wk 0 — baselinenone (all → monolith)0%Proxy inserted in front of everything; p99 unchanged except the ~2 ms extra hop.
Wk 1 — shadowmirror (legacy still answers)0% served, 100% copiedNew svc gets a copy of every request; diff its response against legacy. Found 3 mismatches in date formatting — fix them here, with zero user impact.
Wk 2 — canarysplit5%New svc error rate 0.02% ≈ legacy; p99 180 ms vs legacy's 210 ms.
Wk 3 — rampsplit50%No rise in 5xx; extra read load on the shared DB is within budget.
Wk 4 — cutoverroute100%The legacy /orders/history code path receives 0 requests for 7 days.
Wk 5 — killroute100%Delete OrderHistoryController from the monolith. The monolith is now measurably smaller. Repeat for the next capability.

If any phase regresses, you flip one weight back to 0% and you are instantly on the old system — no rollback deploy, no restore. That reversibility is the pattern's core safety property. One honest qualifier: this instant reversibility is a property of the routing, not the data. It holds fully while the migrated slice is read-only (like /orders/history here) or while both backends share one store. The moment a write route is canaried to a service that owns its own store, flipping the weight back strands every row the new service wrote during the canary — a real rollback plan for a write path needs a data story too (replay the new store's writes into legacy, or keep a sync running both ways during the window). The Key Insights page traces this failure end to end.

The rollback that isn't (write canary at 5%)

tWhat happens
t0POST /orders #101 routed to the new service; committed in the new store
t1Canary regression detected; facade weight flipped back to 0%
t2GET /orders/history now served by the monolith from legacydb — order #101 is missing, and the customer paid for it
t3Recovery = replay the new store's canary-window writes into legacydb (idempotent upsert), then declare the rollback complete

Flip the weight, then reconcile the window — in that order, always.

Pitfalls

When to use it — and when not to

Reach for Strangler Fig when the system is (a) large and business-critical, so downtime and big-bang risk are unacceptable; (b) decomposable into capabilities behind identifiable seams — an HTTP boundary, a message queue, a set of URL prefixes you can route on; and (c) fronted by an interception point where you can insert a facade. These three signals together are what make incremental replacement possible.

Do not use it when the system is small or short-lived — the proxy scaffolding, dual maintenance, and multi-month coordination cost more than the thing you are replacing. Also skip it when there is no clean seam: if everything is coupled through shared in-process state you cannot intercept at a boundary, there is nothing to route.

Trade-offs vs the alternatives

Crisp rule: choose Strangler Fig to migrate a live, critical system across a network boundary one capability at a time; prefer a rewrite for small/throwaway systems; prefer Branch by Abstraction when the seam never leaves the process.

Takeaways


Re-authored and deepened for this guide. Draws on Martin Fowler's "StranglerFigApplication" and "BranchByAbstraction" (martinfowler.com), Sam Newman, Monolith to Microservices (O'Reilly, 2019) — the shadow/parallel-run, canary, and data-decomposition guidance — and Chris Richardson's microservices.io pattern catalog. The strangler fig metaphor originates with Fowler's observation of the trees in Queensland, Australia.

🤖 Don't fully get this? Learn it with Claude

Stuck on Introduction? Open Claude, copy a block below, and it'll teach you this exact concept — visually and interactively.

🎨 Explain it visually

Build the mental picture, not memorization.

I just read a lesson on **Introduction** (System Design) and want to truly understand it. Explain Introduction from first principles using ONE vivid real-world analogy and a visual mental model — draw it as ASCII art or a clear step-by-step diagram — with a concrete example using real numbers. Then ask me one question to check I got the mental picture, and wait for my reply. If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.
🤔 Walk me through it (interactive)

Socratic — adapts to where you're stuck.

Teach me **Introduction** interactively. Ask me ONE guiding question at a time, wait for my answer, and adapt to my confusion — build the idea with me step by step instead of explaining it all at once. If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.
🧪 Quiz me & fix my gaps

Active recall exposes what you missed.

Quiz me on **Introduction** with 5 questions, easy to tricky, ONE at a time. Tell me if each answer is right; at the end, explain clearly what I got wrong and why. If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.
🧠 Make it stick

Intuition + hook + flashcards for long-term memory.

Help me remember **Introduction** for the long term: give the one-sentence intuition, a memorable hook/mnemonic, a tiny worked example, and 3 active-recall flashcards (Q -> A). If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.

📝 My notes