Core Concept

Microservices Patterns: Strangler, Saga, & Outbox

Three patterns for splitting monoliths safely: Strangler Fig routes traffic incrementally; Saga coordinates multi-service workflows with compensations; Outbox publishes events atomically with local DB writes.


1. What It Is

Microservices aren't a day-one choice β€” they're how we decompose a monolith once team boundaries and scale demand it. Strangler fig, saga, and outbox are the patterns interviewers expect you to name.

What:

Core architectural patterns designed to decouple monolithic databases and applications into independent, resilient microservices.

Primary purpose:

Enabling incremental code migrations, maintaining atomic multi-service transactions, and guaranteeing reliable system integration streams.

Usually used for:

Monolith-to-microservices migrations, distributed e-commerce transactions, and outbox event streams.

2. Core Mental Model

How should I think about this inside system architectures?

🌿 The Strangler Fig

Never execute a 'big bang' rewrite. Wrap the old monolith in an API gateway proxy, gradually strangling old features as new microservices replace them.

βš–οΈ Sagas & Compensations

Avoid locking distributed transactions. Run local updates instantly. On failure, fire undo actions in reverse chronological order.

πŸ“¬ Atomic Outbox Delivery

Avoid dual-write failures. Write database state updates and outbox events in a single SQL transaction, using CDC relays to publish events to Kafka.

In the room

Don't microservice everything because it sounds modern. Strangler fig for migration, saga for cross-service transactions, outbox for reliable events. Warn about distributed tracing and deployment complexity as costs.

3. Why It Matters in HLD

Microservices patterns manage migration, consistency, and delivery across service boundaries. Three lenses:

Needed When:

Migrating legacy monolithic codebases to microservices, or building reliable transactional e-commerce checkout systems.

Avoids:

Dual-write data inconsistencies, high-risk migrations outages, tight code dependencies coupling, and lost transactional events.

Optimizes For:

Software release frequencies, deployment independence, transaction consistency boundaries, and migration safeties.

4. Architecture & Data Flow

Walk three patterns as parallel paths. Strangler: proxy routes traffic; new features go to new service; old monolith shrinks. Saga: choreographed or orchestrated steps with compensations on failure. Outbox: atomic local write + outbox row; relay publishes to bus β€” reliable at-least-once.

Diagram A β€” Strangler Fig + Saga

Loading...

Diagram B β€” Transactional Outbox (optional: service mesh for mTLS only)

The outbox diagram below is the critical path for reliable events. Service mesh sidecars (Envoy) are optional infrastructure for mTLS and observability β€” mention briefly, do not over-index unless the interviewer asks about zero-trust networking.

Loading...

In the room

Warn against distributed monolith β€” separate repos that must deploy together is microservices theater. Strangler lets you prove value incrementally.

5. Key Characteristics

Strangler vs big-bang rewrite, saga choreography vs orchestration β€” we compare:

  • Pattern overview β€” migration, distributed workflow, and reliable events:
Design PatternCore Execution MechanicPrimary Architectural Role
Strangler Fig MigrationAPI gateways steer requests incrementally from old monolith code to new microservices.
  • Ensures zero-downtime migrations
  • isolates rewrite risks.
Saga OrchestrationCoordinates multi-step distributed transactions using compensating rollbacks.Maintains eventual consistency across microservice databases.
Transactional OutboxSaves updates and outbox events atomically inside the same local database transaction.Guarantees reliable, at-least-once outbound event delivery.

6. Strategic Tradeoffs

Independent deployability trades distributed complexity β€” we articulate both:

BenefitCost
Decoupled Scaling (allows development teams to deploy and scale independent microservices services autonomously)Operational Complexity (managing distributed transactions, network latency hops, and cluster tracing requires significant tooling)
Incremental Rewrite Safeties (Strangler Fig mitigates big-bang migration rewrite failures by testing routes incrementally)Data Synchronization Lags (maintaining dual-write database syncs during modernizations adds data overhead)

7. Failure / Bottleneck Awareness

Distributed monolith, saga compensation gaps, and outbox relay lag β€” we volunteer:

🌩️ The Database Outbox Table Bloat

Problem: In high-throughput databases (thousands of writes/sec), if the background outbox event relay crashes, the local `outbox` table continues accumulating events rapidly, eventually bloating database disks and degrading queries.

Mitigation: Implement automated, high-speed purging or partition truncation of processed records (`WHERE published = true`) in the outbox table.

🐒 The API Gateway Routing Latency Hop

Problem: Introducing centralized API gateways or sidecar proxies (Envoy) adds extra network serialization and deserialization hops to every request, raising baseline tail latencies (P99).

Mitigation: Deploy lightweight, high-performance C++ sidecars, terminating SSL at edge layers and utilizing high-concurrency gRPC protocols for internal communication.

8. Common HLD Usage

Legacy modernization, e-commerce checkout, and event-driven architectures use these patterns:

Modernization ScenarioPattern SelectionArchitectural Rationale
Legacy Monolith ModernizationStrangler Fig MigrationAn API gateway intercepts /orders endpoints, routing them to a new isolated microservice fleet, keeping /users pointing to the legacy app.
Reliable E-Commerce InvoicingTransactional Outbox + Debezium CDCOrder updates write to database orders and outbox event tables inside a single SQL transaction. CDC relay tails WAL logs to stream events to Kafka.

9. Decision Signals

Reach for strangler when migrating live traffic; saga/outbox when cross-service writes must be reliable:

🎯 Think Microservices Patterns When:
  • You are designing legacy codebase modernizations where rewriting the entire monolith at once is too risky.
  • You must coordinate multi-step workflows spanning different service databases while maintaining consistency.
  • You need to publish transactional events to message brokers without introducing dual-write failure points.

11. Deep Dive (Optional)

The Anti-Corruption Layer (Domain Boundary Protection)

When strangling a legacy monolith, the new microservice must often query legacy tables to fetch user attributes. However, legacy datastores frequently feature convoluted schemas that violate the clean, modern domain model of the new microservice.

Solution: Anti-Corruption Layer (ACL)

  1. Place a dedicated Anti-Corruption Layer adapter between the legacy system and the new microservice.
  2. When the new microservice requests a profile:
    New Service Request: GET /users/123 -> returns clean JSON
  3. The ACL catches the query, maps it to complex legacy calls, translates messy relational table layouts into a clean JSON structure, and returns it.

This prevents legacy domain models from leaking into and corrupting the new microservice codebase, protecting domain boundaries during modernizations.

πŸ’¬Review

Help Us Improve

How helpful was this walkthrough?

Click a star to rate. We actively use this feedback to refine and update our system design content.

Placeholder
Optional but highly appreciated!

Discussion

Share your thoughts, ask questions, or help others.

Loading comments...