Home/Learn/Microservices/Strangler Fig Pattern

Strangler Fig Pattern

Intermediate
Patterns

Incrementally migrate a monolith by routing individual features to new microservices behind an API gateway until the monolith is completely replaced.

Overview

The Strangler Fig pattern (named after a vine that gradually envelops and replaces its host tree) is the safest approach to migrating a monolith to microservices. Instead of a high-risk "big bang" rewrite, you incrementally extract functionality: introduce an API gateway (or reverse proxy) in front of the monolith, then route individual features to newly built microservices one at a time. The monolith shrinks progressively as features are extracted; eventually the monolith handles nothing and can be decommissioned. At no point do you have a "big bang" cutover, and both systems run in parallel — making rollback trivial by toggling a route in the gateway.

The Three Steps: Identify, Route, Extract

Step 1: Add an API Gateway (Nginx, Spring Cloud Gateway, Envoy) in front of the monolith — all traffic flows through it, but initially everything is proxied to the monolith unchanged. Step 2: Extract a bounded capability into a new microservice. Step 3: Update the gateway route to forward that endpoint to the new service. The monolith still handles everything else.

Spring Cloud Gateway — strangler routing phases
# Spring Cloud Gateway — strangler routing config
# Phase 1: everything goes to monolith
spring:
  cloud:
    gateway:
      routes:
        - id: monolith
          uri: http://monolith-service
          predicates: [Path=/**]

# Phase 2: order endpoints → new order-service, rest → monolith
spring:
  cloud:
    gateway:
      routes:
        - id: order-service
          uri: http://order-service
          predicates: [Path=/api/orders/**, /api/order-items/**]
          order: 1

        - id: monolith-fallback
          uri: http://monolith-service
          predicates: [Path=/**]
          order: 100    # lower precedence

Data Synchronisation During Migration

When you extract a service that owns data still in the monolith's DB, you need a data migration strategy. Common approaches: (1) **Shared DB (temporary)** — new service reads/writes the monolith's tables initially, then migrates to its own DB later. (2) **Change Data Capture** — Debezium streams rows from the monolith DB to the new service's DB. (3) **Dual write** — write to both DBs simultaneously during cutover, then switch reads, then drop the monolith table.

Debezium CDC — stream data from monolith during migration
# Debezium CDC — stream monolith DB changes to new service during migration
# connector config (POST /connectors)
{
  "name": "orders-cdc-connector",
  "config": {
    "connector.class": "io.debezium.connector.mysql.MySqlConnector",
    "database.hostname": "monolith-db",
    "database.port": "3306",
    "database.include.list": "monolith",
    "table.include.list": "monolith.orders",
    "transforms": "route",
    "transforms.route.type": "org.apache.kafka.connect.transforms.ReplaceField$Value",
    "topic.prefix": "cdc"
    // CDC events → order-service consumes and syncs to its own DB
  }
}

Anti-Patterns: Big Bang Rewrite and Distributed Monolith

The **big bang rewrite** — stop the monolith, rewrite everything at once, deploy all new services simultaneously — fails most of the time: the new system takes years, business requirements change, and the risk is enormous. The **distributed monolith** anti-pattern happens when you split the code into services but they still share a database, have synchronous coupling chains, and must deploy together — you get all the complexity of microservices with none of the benefits.

Distributed monolith warning signs and checklist
// Distributed monolith warning signs:
//
// 1. Services share the same database schema
//    Orders service: SELECT * FROM inventory.products WHERE id = ?
//    → tight schema coupling
//
// 2. Synchronous call chains: A → B → C → D
//    → one slow service makes the entire chain slow
//
// 3. Services must deploy in a specific order
//    → not independently deployable
//
// 4. A change in one service requires updating another
//    → not independently releasable
//
// Checklist for extracting a service:
// ✓ Owns its own data store
// ✓ Exposes a stable API (versioned)
// ✓ Can deploy, scale, and restart independently
// ✓ Has its own CI/CD pipeline and on-call rotation

Key Points to Remember

  • 1Strangler Fig: add a gateway, route features to new services incrementally, shrink the monolith
  • 2No big-bang cutover — both monolith and services run in parallel; rollback is a route toggle
  • 3Use Debezium CDC or dual-write to migrate data ownership from monolith to new service DB
  • 4A distributed monolith (shared DB + synchronous coupling) is worse than the original monolith
  • 5Each extracted service must be independently deployable, scalable, and own its data
  • 6Extract high-ROI, low-coupling features first (e.g., notifications, reporting)

Interview Questions

Sign in to ask Aria
1

What is the Strangler Fig pattern and how does it differ from a big-bang rewrite?

EasyThoughtWorks
2

How would you handle data migration when extracting a feature from a monolith database?

HardNetflix
3

What is a distributed monolith and how do you recognise one?

MediumAmazon
4

What criteria do you use to decide which feature to extract first?

MediumUber
5

How does Change Data Capture with Debezium help during a strangler migration?

HardConfluent

Ask Aria about Strangler Fig Pattern

Your personal AI tutor — ask anything about this concept

Revision Status

Personal Notes

Sign in to save personal notes for this topic.

Discussion

Sign in to join the discussion.

Loading discussion…