Guide

A saga is a long business operation split into a sequence of local transactions. Each step commits on its own, in its own service. If a later step fails, the saga runs compensating transactions for the steps that already completed, in reverse order. There is no global lock and no two-phase commit.

Concept

A compensating transaction is the designed undo for a step. It is a new action that reverses the business effect of the step, not a database rollback.

Sagas come from Garcia-Molina and Salem's 1987 paper. The idea is old, and it's still the most common way to handle multi-service workflows.

The big idea

Compensation is a semantic undo, not a rollback. You can't un-send an email or un-charge a card. You can send a correction email or issue a refund. So each step needs a designed, tested counterpart.

Walking through a trip booking

A travel site books a flight, a hotel and a rental car as one trip.

StepActionCompensation
T1Create trip record (PENDING)Mark trip CANCELLED
T2Book flight (airline API)Cancel flight booking
T3Book hotelCancel hotel booking
T4Charge cardRefund card
T5Book carCancel car booking
T6Mark trip CONFIRMEDNone. This is the end.

Suppose T5 fails because no cars are available. The saga runs C4 (refund), then C3 (cancel hotel), then C2 (cancel flight), then C1 (mark trip cancelled). The user sees: "We couldn't complete your booking. You've been refunded."

Designing the steps

Three choices make a saga robust.

  • Order steps by how hard they are to undo. Put steps that can't be undone, such as sending a confirmation or shipping goods, after the pivot transaction. The pivot is the point beyond which the saga commits to finishing. Steps after the pivot must be retried until they succeed.
  • Put likely failures early. If car availability often fails, check it before charging the card. Fewer compensations run, and customers see fewer charge-then-refund pairs.
  • Make every step and compensation idempotent. The saga retries steps whose outcome is unknown. See idempotency and retries.

Compensations must not fail permanently. A refund that can't be issued needs retries and, eventually, a queue that a person watches.

Solid arrows are forward steps. Dotted arrows are failures that trigger compensation.

Sagas lack isolation

A saga is atomic eventually, through compensation. It is not isolated. Between the charge (T4) and its refund (C4), other transactions can see the intermediate state. A support dashboard may show a charge for a trip that is about to be cancelled. Another saga may read a hotel room as booked when it is about to be released. Countermeasures:

  • Semantic locks. Mark records PENDING and have other operations treat them carefully. For example, leave pending orders out of revenue reports.
  • Commutative updates. Design updates so order doesn't matter. Increment and decrement, rather than set.
  • Re-read and verify. Check a value again before acting on it in a later step.

Common mistakes

  • Treating compensation as rollback. A refund is a new charge in the other direction, with its own failure modes.
  • Putting irreversible steps early. Once an email is sent, the saga can't undo it.
  • Forgetting that compensations can fail. Give them retries and an escalation path.

Check yourself

1. In the trip saga, the car booking fails. Which compensations run, and in what order? C4 (refund the card), then C3 (cancel the hotel), then C2 (cancel the flight), then C1 (mark the trip cancelled).

2. Why is a saga atomic only eventually? Until the compensations finish, other readers can see the intermediate state, such as a charge on a trip that is about to be cancelled.

Key takeaways

  • A saga is a sequence of local transactions, each with a designed compensation.
  • Compensation is a semantic undo. A refund is not a rollback.
  • Put irreversible steps after the pivot, and make every step idempotent.
  • Sagas are atomic eventually but not isolated, so plan for intermediate states.

Further learning

Caitie McCaffrey's GOTO talk is the classic introduction to sagas in practice, from the 1987 paper to how she applied them at scale on Halo's backend.

Applying the Saga Pattern • Caitie McCaffrey • GOTO 2015GOTO Conferences
Pattern: Saga (microservices.io)Implement transactions using a saga, which is sequence of local transactionsmicroservices.io

Next, see who drives a saga, in orchestration versus choreography.