---
title: "Migrating from Monolith to Microservices with the Strangler Fig Pattern"
description: "An architectural guide to decomposing monolithic codebases using edge proxies, the transactional outbox pattern, and incremental database segregation."
canonical: "https://zainahmed.net/blog/microservices-migration"
published: "2023-11-28"
---

# Migrating from Monolith to Microservices with the Strangler Fig Pattern

> Author: Zain Ahmed
> Published: 2023-11-28
> Read Time: 2 min read
> Category: Architecture
> Tags: Microservices, Architecture, Migration, Kubernetes
> Canonical URL: https://zainahmed.net/blog/microservices-migration

## Excerpt
An architectural guide to decomposing monolithic codebases using edge proxies, the transactional outbox pattern, and incremental database segregation.

---

Decomposing a production monolith through a single cutover rewrite rarely succeeds. Long-running feature branches diverge, database schemas conflict under live traffic, and rollback boundaries become impossible to test. The reliable alternative is the Strangler Fig pattern: intercepting edge traffic and routing discrete bounded contexts to new containerized services while the legacy application remains operational.

## 1. Edge Proxy Routing & Seam Extraction

Before extracting any service, place a reverse proxy or API gateway (such as Envoy, AWS ALB, or Cloudflare Workers) in front of the monolith:

- **Identify natural seams:** Target read-heavy endpoints or self-contained operational modules (e.g., notification dispatches, authentication validation, or invoice generation) where dependencies on core shared tables are minimal.
- **Path-based edge routing:** Route extracted paths (`/api/v1/notifications/*`) to the new microservice running in Kubernetes, forwarding untargeted traffic (`/*`) back to the legacy monolith.
- **Shadow routing (Dark Launching):** Mirror live production traffic to the new service without returning its response to the client. Compare latency percentiles (p95/p99) and error rates against the monolith before cutting over.

## 2. Decoupling the Shared Database

The primary risk in microservices migration is not the application tier: it is database coupling. When multiple services write directly to the same database tables, schema migrations lock shared records and cause distributed deadlocks.

```txt
[Client Request]
       │
   [API Gateway / Envoy]
       ├── /api/v1/orders ────► [Orders Service] ──► [Orders DB]
       │                                                   │ (CDC Event)
       └── /* (Legacy) ───────► [Monolith App]   ◄─────────┘
```

1. **Transactional Outbox Pattern:** When a new service writes to its dedicated database, it inserts an event into an `outbox` table within the same ACID database transaction.
2. **Change Data Capture (CDC):** A log tailer (such as Debezium or AWS DMS) streams events from the database commit log to an Apache Kafka or RabbitMQ topic.
3. **Eventual Consistency:** Downstream consumers (and the legacy monolith) subscribe to these domain events to keep shared reporting data synchronized without direct database connections.

## 3. Safe Cutover and Retirement

Once the new service handles 100% of read and write traffic with verified data integrity:
- Remove deprecated code paths and tables from the legacy monolith.
- Tighten network security policies (e.g., Cilium or Kubernetes NetworkPolicies) so internal services cannot reach deprecated legacy endpoints.
- Repeat the cycle on the next bounded domain until the legacy codebase shrinks to a simple routing stub.

---

## Related Endpoints & Navigation
- **All Articles**: [https://zainahmed.net/blog](https://zainahmed.net/blog)
- **Author Profile**: [https://zainahmed.net/about](https://zainahmed.net/about)
- **Machine-Readable LLM Manifest**: [https://zainahmed.net/llms.txt](https://zainahmed.net/llms.txt)
- **RSS Feed**: [https://zainahmed.net/feed.xml](https://zainahmed.net/feed.xml)
