Skip to content
Saga Pattern: Managing Distributed Transactions Without Two-Phase Commit 2 min

Saga Pattern: Managing Distributed Transactions Without Two-Phase Commit

SD
ScaleDojo
May 11, 2026
2 min read505 words
Saga Pattern: Managing Distributed Transactions Without Two-Phase Commit

The $1,000 Headphone Order Gone Wrong

A customer orders $1,000 headphones. The Order Service creates the order. The Inventory Service reserves the item. The Payment Service charges the credit card. But the card is declined. Now you need to unreserve the inventory and cancel the order - across three separate databases that have no shared transaction. In a monolith, this is one database rollback. In microservices, this is the distributed transaction problem that the Saga pattern solves.

Saga: A Chain of Local Transactions

Saga for Order Placement:

  Happy Path (all succeed):
  [Order Svc]      [Inventory Svc]    [Payment Svc]
      |                  |                  |
  1. Create order    2. Reserve item    3. Charge card
     PENDING             RESERVED           CHARGED
      |                  |                  |
  4. Mark CONFIRMED  <---+---success--------+

  Failure Path (payment declined):
  [Order Svc]      [Inventory Svc]    [Payment Svc]
      |                  |                  |
  1. Create order    2. Reserve item    3. Charge card
     PENDING             RESERVED           DECLINED!
      |                  |                  |
  5. Mark CANCELLED  4. Release item   <---FAIL--------+
     (compensate)        (compensate)

  Each step is a LOCAL transaction in its own DB.
  Compensating transactions undo committed work.

Orchestration vs Choreography

ORCHESTRATION (central coordinator):

  [Saga Orchestrator]
      |          |          |
  1.  +--create->|          |          State Machine:
      |  [Order] |          |          PENDING_ORDER
  2.  +----------+--reserve>|            -> RESERVING_INVENTORY
      |          | [Invent]  |            -> CHARGING_PAYMENT
  3.  +----------+----------+--charge>     -> CONFIRMING_ORDER
      |          |          | [Payment]    -> COMPLETED
  4.  +--confirm>|          |
      | [Order]  |          |

  Pros: clear state machine, easy to debug, visible flow
  Cons: single point of coordination, orchestrator coupling

CHOREOGRAPHY (event-driven, no coordinator):

  [Order] --OrderCreated--> [Inventory]
                            --InventoryReserved--> [Payment]
                                                  --PaymentCharged--> [Order]
                                                  --PaymentFailed--> [Inventory]
                                                                    --InventoryReleased--> [Order]

  Pros: no single coordinator, loosely coupled
  Cons: hard to trace, invisible flow, complex failure paths

Compensating Transactions Are NOT Rollbacks

Compensation vs Rollback:

  Database rollback: UNDO uncommitted changes atomically.
  Compensation:      NEW transaction that reverses committed work.

  Examples:
  Action                 Compensation
  --------------------   -------------------------
  Reserve inventory      Release inventory
  Charge credit card     Refund credit card
  Send confirmation      Send cancellation email
  Create shipping label  Cancel shipping label
  Deduct loyalty points  Credit loyalty points back

  Some actions CANNOT be compensated:
  - Sent a push notification? Cannot unsend.
  - Published to social media? Cannot un-publish.
  - Shipped the package? Need a return process.

  Design compensations BEFORE building the saga.

When to Use Which Style

Factor              Orchestration       Choreography
------------------  ------------------  ------------------
Complexity          Medium              High (at scale)
Debugging           Easy (state machine) Hard (trace events)
Coupling            Orchestrator knows   Services independent
                    all participants
Failure handling    Centralized          Distributed
Best for            Complex sagas (5+)   Simple sagas (2-3)
                    Many failure modes   Few failure modes

Rule of thumb: start with orchestration.
Switch to choreography only when the orchestrator
becomes a bottleneck or single point of failure.

Interview Tip

When designing a multi-service transaction, say: 'Instead of distributed 2PC which locks resources across services, I would use the Saga pattern. Each service performs a local transaction and publishes an event. If any step fails, compensating transactions undo the previous steps. For complex flows with 4+ services, I prefer orchestration - a saga orchestrator manages a state machine tracking the saga's progress. For simple 2-3 step flows, choreography with event-driven communication works well. I would design compensating transactions for every step before building the saga.'

<
Saga Pattern: Managing Distributed Transactions Without Two-Phase Commit - Architecture Diagram
Architecture overview
/blockquote>

Key Takeaway

Sagas replace distributed ACID transactions with a sequence of local transactions plus compensating transactions. Orchestration is easier to reason about and debug. Choreography is more decoupled. Choose based on complexity: simple sagas work fine with choreography; complex sagas with many failure modes benefit from an orchestrator.

Enjoyed this article?

Share it with your network to help others level up their system design skills.

Discussion0

Join the Discussion

Sign in to leave comments, reply to others, or like insights.

Sign In to ScaleDojo

No comments yet. Be the first to start the thread!

Related Articles

Enjoyed this content?

Your support keeps us creating free resources

We put a lot of hours into researching and writing these guides. If it helped you, consider buying us a coffee. Every bit goes toward keeping ScaleDojo's content free and growing.

$

One-time payment via Stripe. ScaleDojo account required.

ScaleDojo Logo
Initializing ScaleDojo