SOFTWARE ARCHITECTURE / SYSTEM CONCEPT BRIEF

Saga pattern

A saga manages a business transaction that spans multiple services by breaking it into a sequence of local transactions, each in one service.

AdvancedPhase 08 / Topic 16 of 17RequirementsTrade-offsFailure modes
01

Overview

A saga manages a business transaction that spans multiple services by breaking it into a sequence of local transactions, each in one service. If a step fails, the saga runs compensating transactions to semantically undo the steps that already succeeded, for example refunding a payment or releasing reserved stock. This provides eventual consistency without distributed locks or two-phase commit.

Sagas can be choreographed (each service reacts to events and emits the next) or orchestrated (a central orchestrator sends commands and tracks state). Orchestration is easier to understand and monitor for complex flows; workflow engines like Temporal, AWS Step Functions, and Camunda make orchestrated sagas durable and observable.

Planning a trip

You book a flight, then a hotel, then a car. If the car rental fails, you do not un-happen the flight; you cancel the hotel and the flight (compensations). Each booking is independent, and cancellations restore a consistent state.

02

When to use it

  • Multi-service business workflows: checkout, booking, account opening.
  • Long-running processes that cannot hold locks.
  • Microservices with a database per service.
  • Workflows that need clear compensation logic.
03

Where it shows up in interviews

Distributed business transactions

Recognize it when: order, payment, and inventory must stay consistent.

  • Design e-commerce checkout with microservices
  • Design a travel booking system
  • Design a food delivery order flow
04

Where it is used in real software

Temporal

Used by Uber, Netflix, Stripe, and Snap for durable workflow orchestration with retries and compensations.

AWS Step Functions

State machines orchestrating Lambda and services, with built-in retries and catch blocks for compensation.

Eventuate Tram

Chris Richardson's framework for choreography and orchestration sagas with the outbox pattern.

05

Key terms

Local transaction
An ACID transaction within one service.
Compensating transaction
Semantic undo of a completed step.
Orchestrator
Central coordinator sending commands and tracking state.
Pivot transaction
Point after which the saga must complete (cannot compensate).
Semantic lock
Marking a record as pending to prevent conflicting changes.
06

How it works, step by step

  1. 1
    Start the saga

    Create the order in PENDING state.

  2. 2
    Execute steps

    Reserve inventory, charge payment, schedule delivery.

  3. 3
    On failure, compensate in reverse

    Refund payment, release inventory, cancel order.

  4. 4
    Make every step idempotent

    Retries and duplicate messages are expected.

  5. 5
    Complete

    Mark the order CONFIRMED; persist saga state throughout.

Orchestrated checkout saga with a failure
Step 1 / 4
Orchestrator
Orders
Inventory
Payments
Shipping

STEP 1Step 1: create order o-981 as PENDING.

07

Steps and compensations

Checkout saga

Step 1 / 5
StepActionCompensation
1Create order (PENDING)Mark order CANCELLED
2Reserve inventoryRelease reservation
3Authorize paymentVoid authorization / refund
4Schedule shipment(pivot: after this, retry until success)
5Confirm order-

NOWStep: 1 | Action: Create order (PENDING) | Compensation: Mark order CANCELLED

Order steps so the hardest-to-compensate actions (shipping, sending emails) come last, after the pivot.

08

Implementation

import { proxyActivities } from "@temporalio/workflow";import type * as activities from "./activities"; const { createOrder, cancelOrder, reserveStock, releaseStock, chargePayment, refundPayment, scheduleShipment, confirmOrder } =  proxyActivities<typeof activities>({ startToCloseTimeout: "30 seconds", retry: { maximumAttempts: 5 } }); // Durable workflow: state survives crashes; each activity is idempotentexport async function checkoutSaga(input: { orderId: string; customerId: string; items: Item[]; totalCents: number }) {  const compensations: (() => Promise<void>)[] = [];  try {    await createOrder(input);    compensations.unshift(() => cancelOrder(input.orderId));     const reservationId = await reserveStock(input.orderId, input.items);    compensations.unshift(() => releaseStock(reservationId));     const paymentId = await chargePayment(input.orderId, input.customerId, input.totalCents);    compensations.unshift(() => refundPayment(paymentId));     await scheduleShipment(input.orderId); // pivot    await confirmOrder(input.orderId);  } catch (err) {    for (const undo of compensations) await undo(); // reverse order    throw err;  }}
09

Complexity and performance

Messages~2 per step (+2 per compensation)

Commands and replies.

ConsistencyEventual

Intermediate states visible.

10

Trade-offs

Availability vs isolation

Sagas avoid distributed locks and stay available, but other requests can see intermediate states (lack of isolation); use semantic locks like PENDING statuses.

Choreography vs orchestration

Choreography is decoupled but hard to follow; orchestration is explicit and observable but centralizes flow logic.

11

Variants and related techniques

Choreography saga

Services react to each other's events.

Orchestration saga

A workflow engine or saga orchestrator drives steps.

TCC (Try-Confirm-Cancel)

Reserve resources first, then confirm or cancel all.

12

Common mistakes

  • Non-idempotent steps or compensations.

    Fix: Every step will be retried; use idempotency keys.

  • Compensations that can fail permanently.

    Fix: Design compensations to always eventually succeed; retry and alert.

  • Irreversible actions early (sending an email).

    Fix: Place them after the pivot.

13

Interview questions

What is a saga and why use it instead of 2PC?

A saga is a sequence of local transactions with compensating actions on failure. It avoids 2PC's blocking locks and tight coupling across services, providing eventual consistency and high availability in microservices.

Orchestration or choreography for checkout?

Orchestration for the core checkout: the steps, compensations, timeouts, and state are explicit and observable in one place (Temporal or Step Functions). Notifications and analytics can react to events via choreography.

14

Practice problems

ProblemDifficultyWhat it trains
Define steps and compensations for hotel bookingMediumCompensation design.
Implement an orchestrated saga with retriesHardDurable workflows.