Saga Pattern

Mental model

A Saga is a sequence of local transactions across services, connected by events or commands. If a later step fails, previously completed work may need a compensating action.

E-Commerce Example

flowchart TD
    A["Order Created"] --> B["Reserve Inventory"]
    B --> C{"Reserved?"}
    C -->|Yes| D["Process Payment"]
    C -->|No| X["Cancel Order"]

    D --> E{"Payment OK?"}
    E -->|Yes| F["Create Shipment"]
    E -->|No| G["Release Inventory"]
    G --> X

    F --> H["Order Completed"]

Why Do We Need It?

Suppose:

Order DB       ✓
Inventory      ✓
Payment        ✗

We cannot simply roll back the PostgreSQL transaction in Order Service because the inventory operation happened in another service/database.

Instead:

Reserve Inventory

Payment fails

Release Inventory

Cancel Order

ReleaseInventory is a compensating action.

Saga Is NOT a Distributed Transaction

This distinction matters.

Saga2PC
Application-level workflowDistributed transaction protocol
Local transactionsCoordinated transaction
CompensationRollback/prepare protocol
Eventual consistency is commonStronger atomicity goal
Services remain autonomousTighter coordination
Usually more operationally resilientCan involve blocking/coordination overhead

Important

A compensating transaction is not the same thing as a database rollback.

If an email was sent, for example, you cannot literally “roll back” the email. You need a new compensating action if one exists.

Orchestration vs Choreography

Orchestration

One component coordinates the workflow:

Saga Orchestrator

      ├── Reserve Inventory
      ├── Process Payment
      └── Create Shipment

Advantages:

  • centralized workflow
  • easier to understand
  • easier to monitor
  • explicit failure handling

Choreography

Services react to events:

OrderCreated

InventoryReserved

PaymentCompleted

ShipmentCreated

Advantages:

  • fewer central orchestration components
  • services react independently

But complex workflows can become difficult to understand.

Project choice

For this learning project, start with orchestration because it makes the workflow and failure handling easier to reason about.

Idempotency Is Required

Imagine:

ReserveInventory

Inventory reserves item

response lost

Saga retries

ReserveInventory AGAIN

Inventory must safely handle the duplicate.

So Saga depends heavily on:

Idempotency

Outbox + Saga

These patterns work together:

Local transaction

      ├── business state
      └── outbox event


             Kafka


        Next Saga step

Remember

Outbox makes events reliable. Saga coordinates business workflow. Idempotency makes retries safe.

Interview Questions

Why not use 2PC everywhere?

2PC provides distributed transaction coordination but introduces coupling and coordination overhead. Many microservice architectures prefer local transactions plus asynchronous workflows and compensation.

What happens if compensation fails?

The Saga must persist its state and retry/alert the failed compensation. In a production system, this becomes an operational concern requiring monitoring, retry policies, and possibly manual intervention.

Does Saga guarantee consistency?

It provides a way to coordinate toward a consistent business outcome, but intermediate states are often visible. It commonly uses eventual consistency.

Next

CAP Theorem and Consistency Models