Saga
A pattern for a long, multi-step transaction across services: each step has a compensating action; failures run compensations to undo prior steps. Avoids holding distributed locks like 2PC. Gives eventual consistency, not atomicity.
- Multi-service business processes (order → payment → shipping).
- Long-running transactions where 2PC would block.
- When atomicity/isolation is required (use 2PC or a single DB).
- When compensations can't undo side effects.
Definition
A saga breaks a distributed transaction into a sequence of local transactions, each with a compensating transaction. If a step fails, compensations run in reverse to semantically undo. Coordination is centralized (orchestration) or event-driven (choreography).
Why it exists
2PC blocks and doesn't scale across services or long durations. Sagas let each service commit locally and undo via compensations, enabling long-running, cross-service business processes without distributed locks.
How it works
Execute step 1, then step 2, etc. On failure at step N, run compensations for steps N-1..1. Each step is a local ACID transaction. The overall saga is eventually consistent, not atomic — intermediate states are visible.
Scaling limits
Intermediate states are observable (not isolated). Compensations must be idempotent and correct, which is hard. Orchestration adds a central coordinator; choreography is decoupled but harder to trace.
Cost shape
No long-held locks (good). Cost is designing correct compensations and handling non-undoable side effects (e.g., an email sent).
Alternatives
- Two-phase commit — Atomic and isolated, but blocking and slow.
- Event sourcing — Audit + replay; sagas often sit on top.
Failure modes
- Compensations that don't truly undo (sent emails, charges).
- Lost/orphaned saga state.
- Non-idempotent steps under retries.
Related terms
Two-phase commit (2PC), Event sourcing, Idempotency, Exactly-once delivery