Saga pattern for distributed transactions — choreography… — Cracked Java
// High-Level Design (HLD / Distributed Systems) · Microservices, Service Mesh, API Gateway
SeniorSystem DesignBig TechAmazon

Saga pattern for distributed transactions — choreography vs orchestration.

The Saga pattern — choreography vs. orchestration

Once each service owns its own database, a single business operation that spans services — place an order, reserve inventory, charge payment, schedule shipping — can no longer be one ACID transaction. There is no distributed lock you'd want to hold across services, and two-phase commit (2PC) is avoided in practice because it blocks and couples availability to the slowest participant. The Saga pattern is the standard alternative.

The core idea

A Saga is a sequence of local transactions, one per service. Each local transaction commits independently and publishes an event (or triggers the next step). If a step fails, the Saga runs compensating transactions that semantically undo the work already committed by prior steps — there is no global rollback, so each "undo" is an explicit business action (refund the charge, release the reservation).

Two coordination styles

Choreography — no central coordinator. Each service listens for events and reacts, emitting its own events that the next service consumes. The workflow is emergent from the chain of event reactions.

Orchestration — a central orchestrator (a Saga coordinator service) explicitly tells each service what to do and when, and drives compensation on failure. The workflow lives in one place.

Orchestrated order Saga: the orchestrator drives each step and compensates on failure

Choosing between them

AspectChoreographyOrchestration
CoordinationDistributed — services react to eventsCentral orchestrator drives steps
CouplingLoose — no central dependencyServices depend on the orchestrator
Workflow visibilityImplicit, spread across servicesExplicit, in one place
Best forFew steps, simple linear flowsMany steps, complex branching
Failure handlingEach service knows its compensationsOrchestrator owns compensation logic
RiskHard to follow / cyclic event chainsOrchestrator can become a god-service
  • Choreography suits short, simple flows where loose coupling matters and the chain is easy to follow. It degrades badly as steps multiply — the logic is scattered across services and the event web becomes hard to reason about or debug.
  • Orchestration suits complex, multi-step workflows with real branching and compensation. Centralizing the state machine makes the flow explicit, observable, and easier to change — at the cost of a component every participant depends on (keep it a coordinator, not a place where business logic accretes).

The outbox connection

Each Saga step does two things: commit its local DB change and publish an event. Doing both is the dual-write problem — if the DB commits but the publish fails (or vice versa), the Saga stalls or diverges. The fix is the outbox pattern: write the event into an outbox table in the same local transaction as the business change, then a relay (or CDC) reliably publishes it afterward. Outbox is what makes each Saga step atomic and reliable; the two patterns almost always appear together.

Mark your status