← Concepts

阅读中文版本

Strangler Fig

The strangler fig pattern replaces a legacy system incrementally by routing slices of traffic to new implementations until the old system can be retired.

architecture

Definition

The strangler fig pattern migrates a legacy system gradually. A routing layer directs a growing subset of traffic to new implementations while the old system continues to serve the rest. Each migrated slice is verified in production, and the old system shrinks until it can be decommissioned. The pattern avoids a single big-bang rewrite and keeps the business running during the transition.

Context and scope

Strangler fig is used for legacy modernization, framework migrations, and monolith decomposition where a full rewrite would take too long or carry too much risk.

Common misconceptions

  • The old system must be frozen — it usually keeps changing, so the routing layer and data sync must handle both
  • Strangler fig is only for UI routes — APIs, background jobs, and data ownership can be migrated the same way
  • The migration ends when traffic moves — data ownership, writes, and the old system's decommission must also be completed

Anti-patterns

  • Migrating a slice without a rollback route to the old implementation
  • Keeping two sources of truth for the same data indefinitely
  • Declaring victory before the old system is actually retired

Related concepts

Authoritative source

https://martinfowler.com/bliki/StranglerFigApplication.html

Route slices, not the whole system

A big-bang rewrite concentrates risk into one release. The strangler pattern moves one slice at a time behind a routing layer. The new slice handles real traffic, is compared with the old behavior, and can be routed back if it fails. The old system remains authoritative for the slices it still owns.

/checkout/*      -> new checkout service
/orders/*        -> new orders service
/catalog/*       -> legacy monolith (until migrated)

The routing layer can be an API gateway, a reverse proxy, or a feature flag. The important property is that routing is reversible and observable. A slice without a rollback route is a big-bang release disguised as incremental migration.

Data is the hard part

Routing reads is easy; moving writes and ownership is not. During the transition, both systems may need to read the same data. Use a shared database only as a temporary bridge, with a clear owner and a plan to split it. If both systems write, define which one is authoritative and how changes propagate. An outbox or change data capture can keep a read model fresh without making both systems primary.

Retire the old system

A migration is not complete when traffic reaches zero. Decommission the old routes, revoke its credentials, delete or archive its data according to policy, and remove the routing exception. A legacy system kept “just in case” continues to cost money, receive patches, and pose a security risk.

When to use it

Use strangler fig when a legacy system is too large or risky for a full rewrite and the business needs continuous delivery during the transition. The advantage is bounded risk and continuous learning; the drawback is a long period of dual running, routing complexity, and data reconciliation. Compared to a rewrite, it is slower to reach a clean architecture but far less likely to fail all at once.