Saga Pattern Diagram: Orchestration vs Choreography

How the saga pattern keeps data consistent across services without distributed transactions: compensations, pivot steps, orchestration vs choreography and a diagram.

· Founder & developer

Published

Saga Pattern Diagram: Orchestration vs Choreography

Placing an order touches three services: inventory reserves stock, payments authorizes the card, shipping creates a shipment. In a monolith that is one database transaction. Split into services with their own databases, there is no transaction that spans all three, and two-phase commit across services is rarely an option in practice.

The saga pattern is the standard answer. This post explains how a saga works, the difference between orchestration and choreography, how compensations and pivot steps fit together, and the isolation problems sagas do not solve for you. The diagram shows an orchestrated order saga.

What a saga is

A saga is a sequence of local transactions. Each step commits in its own service's database and triggers the next. If a step fails, the saga runs compensating transactions that undo the effects of the steps that already committed.

The idea is older than microservices: Hector Garcia-Molina and Kenneth Salem described sagas in a 1987 paper about long-lived database transactions. The pattern came back because service boundaries recreated the same problem.

Two consequences shape everything else:

  • Eventual consistency. Between the first and last step, the system is in an intermediate state that other requests can see. The order is PENDING, the stock is reserved, the card is authorized but not captured.
  • Compensation is not rollback. You cannot un-send an email or un-charge a card silently. A compensation is a new business action, such as voiding an authorization or issuing a refund, that semantically reverses the earlier one.

Compensable, pivot and retryable steps

Classify every step before drawing anything. The Azure Architecture Center's saga pattern guide uses three kinds:

Kind Meaning Example
Compensable Can be undone by another transaction Reserve stock; authorize payment
Pivot The point of no return: once it succeeds, the saga must finish Create the shipment
Retryable Comes after the pivot and must eventually succeed; idempotent Send the confirmation email

Order matters. Put compensable steps first, the pivot next, and only retryable steps after it. If the pivot fails, compensate; once it succeeds, retry everything after it until it succeeds. A saga with a compensable step after the pivot cannot reach a consistent state when that step fails.

Orchestration vs choreography

There are two ways to coordinate the steps.

Orchestration: a saga orchestrator, often a state machine with durable state, tells each service what to do and waits for the reply. It owns the sequence, the retries, the timeouts and the compensations.

Choreography: there is no coordinator. Each service listens for events and reacts: inventory hears OrderCreated and reserves stock, payments hears StockReserved and authorizes, and so on. Failures are events too, and each service knows which compensation to run.

Orchestration Choreography
Where the flow lives One place: the orchestrator Spread across services' event handlers
Adding a step Change the orchestrator Change who listens to which event
Seeing the state of one order Query the saga log Reconstruct it from events
Coupling Services know the orchestrator's commands Services know each other's events
Good fit Many steps, branching, strict ordering Two or three steps, simple flows

Choreography is pleasant for short flows and painful when someone asks "why is order 8812 stuck?". Orchestration gives that question one place to look. Workflow engines such as Temporal, AWS Step Functions or Camunda provide durable orchestration so you do not build the state machine yourself. Chris Richardson's saga pattern page has worked examples of both styles.

Isolation: the part sagas leave to you

A database transaction hides intermediate state from other transactions. A saga does not. While an order saga is running, another request can read the reserved stock, or a second saga can modify the same record. The usual countermeasures:

  • Semantic lock. Mark records as in progress (an order in PENDING, stock in RESERVED) so other operations know to wait or refuse.
  • Commutative updates. Design operations so they give the same result in any order, such as incrementing and decrementing counts instead of setting them.
  • Reread before writing. Check that a value has not changed since the saga read it, and fail or restart if it has.

Make every step and every compensation idempotent, keyed by the saga ID and step. Messages will be delivered twice, and a retried "void authorization" must not void a different payment.

Timeouts and stuck sagas

Every step needs a deadline. A payment service that never answers leaves the saga waiting forever and the stock reserved. Give each step a timeout, treat a timeout as a failure before the pivot (compensate) and as a reason to retry after it, and alert on sagas that stay in one state longer than expected. A small dashboard of sagas by current step answers most support questions on its own. Record why each saga ended, too.

The architecture diagram

An order service starts a saga in an orchestrator that logs each step and calls inventory, payment and shipping services in order. A decision checks whether all steps succeeded: yes leads to order approved, no leads to compensation in reverse order and order rejected.

11 components · 9 connections

Open in Archboard
Diagram contents
  • Order service
  • Saga orchestrator
  • Saga log
  • Inventory service
  • Payment service
  • Shipping service
  • All steps succeeded?
  • Order APPROVED
  • Compensate in reverse order
  • Order REJECTED
  • start
  • persist each step
  • 1. reserve stock
  • 2. authorize payment
  • 3. create shipment
  • yes
  • no
  • void, release
An order saga run by an orchestrator. It reserves stock, authorizes payment and creates the shipment as local transactions, persists every step, and if a step before the pivot fails it compensates the earlier steps in reverse order.

How to read it:

  • Left: the order service creates the order in PENDING and starts the saga.
  • Middle: the orchestrator runs the steps in order and persists each one to the saga log, so a restart resumes where it stopped.
  • Right: the three services, each labeled with its step number and kind. Inventory and payment are compensable; shipping is the pivot.
  • Bottom: if all steps succeed the order becomes APPROVED. If a step before the pivot fails, the orchestrator compensates in reverse order (void the authorization, then release the stock) and the order becomes REJECTED.
  • The Markdown table pairs every action with its compensation, which is the first thing a reviewer should check.

What to put on a saga diagram

  • The step order and each step's kind. Compensable, pivot or retryable belongs on the box.
  • Every compensation. A step without one is either the pivot, retryable, or a bug.
  • Where saga state lives. A saga that cannot survive a crash halfway through is not finished.
  • The visible intermediate states. PENDING and RESERVED are part of the design; other features will see them.

Sagas pair naturally with the transactional outbox pattern, because each step must update its database and send a message without losing either. The microservices architecture diagram shows where these services sit, and the payment gateway integration diagram covers the authorization and capture steps in detail.

Build it in Archboard

  1. Sign in with Google or GitHub and create a diagram.
  2. Add Container nodes from the C4 Model pack for the order service, the saga orchestrator and the three participating services, and a Database for the saga log.
  3. Put the step number and kind (compensable or pivot) in each service's technology field.
  4. Add a Decision, a Process and two Terminator nodes from the Flowchart pack for the success and compensation paths.
  5. Add a Markdown block from the Core pack with a table of actions and compensations.

The example uses 11 diagram nodes, within the Free plan.

FAQ

What is the difference between a saga and a distributed transaction? A distributed transaction (two-phase commit) locks resources across databases until everyone commits. A saga commits each step locally and undoes earlier steps with compensations if a later one fails, trading isolation for availability.

Should I use orchestration or choreography? Orchestration for flows with many steps, branches or strict ordering, because the state of each saga lives in one place. Choreography for short flows where two or three services react to each other's events.

What is a pivot transaction? The step after which the saga can no longer be compensated. Everything before it must be compensable; everything after it must be retryable until it succeeds.

How do I handle failures in a compensation? Retry it. Compensations must be idempotent and eventually succeed; if one cannot, the saga needs a manual resolution path and an alert.

Do sagas give me isolation? No. Other requests can see intermediate states. Use semantic locks such as PENDING states, commutative updates and rereads to prevent the anomalies that matter to your business.

Start free — one seat, no credit card.

Related posts

← Back to blog

Open a canvas in a minute

Sign in with Google or GitHub. Free for a single seat. Upgrade when the team joins.