Design Patterns Tutorial 0/70 lessons ~6 min read Lesson 50

    Saga Pattern

    Saga manages distributed transactions as a sequence of local transactions with compensating actions on failure.

    Course progress0%
    Focus
    21 guided sections
    Practice signal
    Examples included
    Career prep
    Interview Q&A included

    Introduction

    Saga manages distributed transactions as a sequence of local transactions with compensating actions on failure. No 2PC across microservices — each service commits locally, publishes event, next step triggers. Failure runs compensations (cancel reservation, refund payment) to reach eventual consistency.

    The story

    Travel booking needed flight + hotel + car across 3 vendor APIs — 2PC impossible. Choreography saga: each service publishes events; next reacts. Failures trigger compensating transactions. Bookings completed reliably without distributed locks.

    The business problem

    Distributed ACID is impossible or impractical across services:

    • Partial failure: flight booked, hotel fails — customer charged wrong.
    • 2PC unavailable: external vendor APIs don't support XA transactions.
    • Lock amplification: distributed locks don't scale across HTTP.
    • Manual reconciliation: ops fixes inconsistent cross-service state.

    The problem teams faced

    Saga fits when:

    • Business transaction spans multiple services/databases.
    • Each step can commit locally but global atomicity needed eventually.
    • Compensating actions exist for each step (cancel, refund, release).
    • 2PC/XA not available or too slow across boundaries.

    Understanding the topic

    Intent: Sequence of local transactions with compensations instead of global rollback.

    • Choreography — each service listens and publishes; no central coordinator.
    • Orchestration — central saga manager issues commands and handles failures.
    • Compensating transaction — semantic undo (CancelBooking, RefundPayment).
    • Idempotency — every step and compensation safe to retry.

    Internal architecture

    Orchestrated travel booking saga:

    ts
    class BookTripSaga {
    async run(trip: TripRequest) {
    try {
    const flight = await this.flights.reserve(trip.flight)
    const hotel = await this.hotels.reserve(trip.hotel)
    await this.cars.reserve(trip.car)
    } catch (e) {
    if (hotel) await this.hotels.cancel(hotel.id)
    if (flight) await this.flights.cancel(flight.id)
    throw e
    }
    }
    }
    // Each reserve() is local TX + idempotent + publishes event

    Visual explanation

    Three diagrams cover saga flow, compensation, and choreography vs orchestration:

    Happy path saga
    Book flight
    Step 1 · commit
    Book hotel
    Step 2 · commit
    Book car
    Step 3 · commit
    Complete
    Saga done
    Each step local transaction + event to trigger next.
    Failure + compensation
    Flight OK
    Committed
    Hotel fails
    Step 2 error
    Cancel flight
    Compensate 1
    Notify customer
    Failure path
    Compensations run reverse order — not DB rollback.
    Choreography vs orchestration
    Few steps · clear?
    Choreography
    Complex · many steps?
    Orchestrator
    Event reactions
    Decentralized
    Saga manager
    Temporal · central
    Orchestration easier to trace; choreography simpler for linear flows.

    Informative example

    Before / after — hope-and-pray HTTP chain to saga:

    ts
    // ❌ No compensation — partial booking on failure
    await flightApi.book(flight)
    await hotelApi.book(hotel) // fails — flight still booked
    await carApi.book(car)
    // ✅ Saga with compensation
    const sagaId = uuid()
    try {
    const f = await flightApi.reserve(sagaId, flight)
    const h = await hotelApi.reserve(sagaId, hotel)
    await carApi.reserve(sagaId, car)
    } catch (e) {
    await hotelApi.compensate(sagaId) // cancel if reserved
    await flightApi.compensate(sagaId)
    throw new BookingFailedError(sagaId, e)
    }

    Execution workflow

    1Saga implementation workflow
    1 / 4

    Define steps

    List local transactions in order.

    Each with compensation action.

    Real-world use

    Temporal/Cadence workflows, Axon Saga, microservices order fulfillment, travel booking, e-commerce checkout across inventory/payment/shipping services.

    Production case study

    Travel booking 3-vendor saga:

    • Challenge: flight + hotel + car; 2PC impossible across vendors.
    • Decision: choreography saga with compensating cancels.
    • Outcome: reliable bookings; failures cleanly compensated.

    Trade-offs

    • Pro: eventual consistency without 2PC; works across external APIs.
    • Con: compensations are semantic — not automatic rollback.
    • Con: debugging distributed saga state harder than single TX.

    Decision framework

    • Use when transaction spans services and 2PC unavailable.
    • Orchestration when steps >5 or complex branching.
    • Choreography when linear and teams own each service.
    • Every step needs defined compensation or accept inconsistency.

    Best practices

    • Saga ID on every message — correlate steps.
    • Idempotent reserve/compensate handlers — at-least-once delivery.
    • Persist saga state — survive process crash mid-saga.
    • Visible saga status for customer support.

    Anti-patterns to avoid

    • Saga without compensations — leaves orphan reservations.
    • Choreography soup — 12 listeners, untraceable flow (use orchestrator).
    • Assuming compensate equals undo — refund may take days.

    Common mistakes

    • Compensation fails — need retry and manual intervention playbook.
    • Non-idempotent steps double-charge on retry.

    Debugging tips

    • Saga state table: sagaId, step, status, last error.
    • Distributed trace with saga ID across all service calls.

    Optimization strategies

    • Temporal stores saga state durably — prefer for long-running sagas.

    Common misconceptions

    • Saga ≠ 2PC. Eventual consistency — intermediate states visible.
    • Saga is Mediator/Orchestrator at workflow scale (behavioral link).
    • Compensate ≠ rollback — semantic business undo.

    Advanced interview questions

    Interview Prep

    Practice concise answers, then expand each card for the explanation.

    3 questions
    1IntermediateQuestionSaga vs 2PC?+

    Answer

    2PC: atomic all-or-nothing across DBs — blocking, doesn't work across HTTP vendors. Saga: local commits + compensations — eventual consistency.

    Follow-up

    Travel booking?
    2AdvancedQuestionChoreography vs orchestration?+

    Answer

    Choreography: services react to events, decentralized. Orchestration: central manager sends commands — easier trace/debug, Temporal pattern.

    Follow-up

    When orchestration?
    3AdvancedQuestionCompensation example?+

    Answer

    Reserve inventory → compensation ReleaseInventory. Charge card → RefundPayment. Must be idempotent.

    Follow-up

    Refund takes 3 days?

    Summary

    You can design sagas with compensations, pick choreography vs orchestration, and explain vs 2PC. Tell the travel booking story — if you can do that, you own Saga.

    Ready to mark this lesson complete?Track your journey across the entire course.