Back to the map

Module 12 · Microservices patterns · Lesson 7 of 8

Strangler fig

Replacing a legacy system incrementally: put a routing facade in front, move one capability at a time to the new system, and retire the old one when nothing routes to it. Choosing the first slice.

CoreNice-to-knowSenior 11 minPro Updated Nov 2026

Why it matters

Every long-lived company has a system that everyone wants to replace and nobody can switch off: too many features, too many unknown dependencies, too much risk in a single cutover. Big-bang rewrites of such systems fail so reliably that the pattern for avoiding them has a name. The strangler fig grows around a host tree, gradually replaces it, and eventually stands on its own; the pattern does the same to a legacy system, one capability at a time, with traffic always flowing. It is the honest answer to "how would you modernise this".

The idea

  1. 1

    Put a facade in front

    Route all traffic to the legacy system through a layer you control: a gateway, a proxy or a thin API. Nothing changes for callers; you have gained a place to make routing decisions.
  2. 2

    Move one capability

    Build one capability in the new system (a bounded context, a feature, an endpoint group). Route its traffic from the facade to the new system. Everything else still goes to the legacy system.
  3. 3

    Repeat

    Capability by capability, the new system takes over routes. Each move is small, reversible (flip the route back) and observable.
  4. 4

    Retire

    When no route points at the legacy system, switch it off. The facade may remain as the gateway or be removed.
ClientsFacaderoutes per capability/catalogue, /search/orders, /billing, …New system2 of 7 capabilitiesLegacyshrinkingdata sync during overlap
A facade routes each capability to either the legacy system or the new one. Capabilities migrate one at a time; the legacy system shrinks until nothing routes to it.

Choosing the first slice

Pick a capability that is valuable enough to justify the work, loosely coupled enough to extract cleanly, and low-risk enough that a problem is survivable: a read-heavy feature, a new feature that would have been built in the legacy system anyway, or an edge capability with few dependencies. Avoid starting with the core transaction the business depends on. Early wins build the tooling (facade, routing, monitoring, data sync) that every later slice reuses.

Data during the overlap

The hard part is rarely routing; it is data that both systems need. Options, roughly in order of preference:

ApproachHowFits
New system owns it, legacy reads via APIMigrate the data once; legacy calls the new system for that dataWhen the legacy system can be modified
Change data capture from legacyThe new system subscribes to the legacy database's changes and keeps its own copyWhen the legacy system cannot change and remains the writer for a while
Dual write through the facadeThe facade or a service writes to both during migrationShort overlaps; risky because of the dual-write problem, so reconcile continuously
Parallel runSend requests to both, compare outputs, serve from oneValidating the new implementation before switching reads

Whatever the approach, add a reconciliation job that compares the two systems and reports drift; migrations without one discover their bugs from customers.

The anti-corruption layer

The legacy system's data model is usually not the model you want. An anti-corruption layer sits between the two: it translates the legacy model into the new domain model and back, so the new system's code stays clean and legacy concepts do not leak in. It lives at the boundary (in the facade, in an adapter, in the CDC consumer) and is deleted with the legacy system.

Branch by abstraction does the strangler move inside one codebase: introduce an interface over the old implementation, build the new one behind the same interface, switch with a flag, delete the old. Feature flags control routing per capability and per user percentage so migrations can be canaried. Parallel runs with output comparison give confidence before switching.

Why big bangs fail

A rewrite that ships only when everything is done has no feedback for months or years, must reproduce every undocumented behaviour at once, freezes the old system's evolution while the business keeps asking for changes, and cuts over in one terrifying night. The strangler fig delivers value and learns from production from the first slice, keeps the old system changeable, and never has a night where everything must work.

Strangler fig · Backplane