Developer Tools

Saga Pattern: Orchestration, Choreography and Compensation

Design a distributed business workflow around durable progress, explicit compensation and duplicate delivery.

AiFolder Editorial Team

AiFolder Editorial Team

5 min read

Updated Oct 9, 2026

Five porcelain domino-shaped service stations linked by red thread, one station fallen and an elegant return loop restoring previous stations; transaction compensation
Original AiFolder editorial illustration

A saga coordinates local transactions

A saga splits a business workflow into steps that commit in different services. If a later step fails, compensation attempts to restore an acceptable business state. Compensation is a new action, not a time machine that erases every observable effect. Microsoft's saga guidance explains the coordination models and transaction categories.

Consider an order that reserves stock, authorizes a payment and confirms delivery. Each service can commit locally. No ordinary database transaction spans every independent service and external provider. You need to specify the outcome when payment fails after stock is reserved.

Two coordination models

Model Coordination Useful pressure
Orchestration A coordinator commands steps and tracks progress A complex workflow needs one visible state machine
Choreography Participants react to events A small event-driven flow with clear ownership

An orchestrator can become complex, but it makes the workflow's status explicit. Choreography removes the central command path, while making a long chain harder to trace. Neither eliminates duplicate events, timeout ambiguity or versioned contracts.

An order fails after money has been reserved

Consider an order workflow that reserves inventory, authorizes a payment and books a shipment. The shipment service times out. That timeout does not say whether a booking exists, so the workflow must query or reconcile before deciding how to compensate. Simply replaying all previous steps can reserve inventory twice or create another authorization. A saga therefore needs durable step identities and explicit outcomes, not just a sequence of HTTP calls.

Compensation is a new business operation. Releasing a reservation is often straightforward; refunding a captured payment may involve fees, delays and customer communication. An email already sent cannot be unsent. Design those outcomes with the product team before implementing the happy path. Persist the workflow state and the external references needed for recovery after a process restart. Each step and compensation should tolerate duplicate delivery, because the coordinator can fail between receiving a response and storing that response. A clear state machine makes ambiguity visible and lets operations distinguish retryable work from cases requiring human judgment.

An order fails after money has been reserved: Reserve stock → Authorize payment → Book shipment → Compensate
An order fails after money has been reserved. Original AiFolder explanatory diagram; illustrative workflow.

Choose where the workflow is visible

Orchestration places the sequence and recovery decisions in a coordinator. It can make a complex order flow easier to inspect, but the coordinator must be durable and its responsibilities should stay focused. Choreography lets services react to events without one central sequence controller. That can suit simpler flows, while long chains become harder to understand when event names and implicit dependencies are scattered across teams. Neither style removes the need for idempotent handlers and observable state.

Compare designs by answering who knows that an order is complete, who decides that a timeout is permanent, and who initiates a refund. If those answers require searching several services' logs, the workflow boundary needs improvement. Avoid putting every downstream concern into one global event; distinct business events and stable identifiers make evolution safer. Define compensation ownership beside the forward step. A service that reserves an item should expose a documented way to release that reservation, including what happens after expiry. Keep exceptional cases explicit rather than forcing an irreversible operation into a misleading automatic rollback path.

Choose where the workflow is visible: Orchestration → Choreography → Compensation → Manual review
Choose where the workflow is visible. Original AiFolder explanatory diagram; illustrative workflow.

Write the failure table first

Completed step Later failure Example compensation
Stock reserved Payment rejected Release reservation
Payment authorized Delivery unavailable Void authorization where supported
Delivery confirmed Customer cancellation Follow a separate cancellation policy

These are illustrative business policies. A payment provider's contract determines which actions are actually possible. An already dispatched parcel cannot be undone by rolling back a row. Keep irreversible steps late where the workflow permits it.

Make progress durable

Store the saga identifier, current state, attempts and external references. Every step and compensation should tolerate repeated delivery. If a worker times out after an external success, reconcile before invoking the operation again. Use stable operation keys and a state transition that prevents stale workers from overwriting later progress.

An outbox places an event record in the same transaction as the local business change. The publisher can retry delivery later. Consumers still need deduplication: an outbox solves the local commit/publication gap, not universal exactly-once behavior.

When a saga is unnecessary

If the state lives in one database and can be changed in one short transaction, use that transaction. Introducing a saga creates recovery, monitoring and support obligations. Before decomposing a workflow, explain the independent ownership or scaling benefit that pays for those costs.

Run failure drills at every boundary, including after a side effect but before acknowledgment, and after compensation but before its completion record. Inspect final business state and unresolved cases. Read idempotency keys and monolith vs microservices for the surrounding design decisions.

Recover one workflow without replaying the world

An operator investigating a failed order should begin with its saga identifier and durable transition history. A command to replay all events is too broad when some effects are already complete. Reconcile the uncertain step with its destination, record the authoritative outcome and resume only the transition whose preconditions now hold. If the destination cannot answer, move the workflow into an explicit review state and expose the customer impact.

Useful fault scenarios include a duplicate completion event, a compensation timeout, a process restart after sending a request and a late success after the coordinator has begun recovery. The expected result is a coherent business state, not merely an empty queue. Track age in each state, compensation backlog and the number of manual interventions. These reveal problems that an overall success percentage hides. Bound automatic retry attempts with backoff and keep the workflow durable across that waiting period. The recovery design should make it possible to explain what happened to one customer's order without pretending that distributed side effects share a single database rollback.

Recover one workflow without replaying the world: Find saga ID → Inspect step state → Reconcile destination → Resume one transition
Recover one workflow without replaying the world. Original AiFolder explanatory diagram; illustrative workflow.

Further reading for these examples

Topics

AiFolder Editorial Team

Written by

AiFolder Editorial Team

Practical technology guides with clear sources, examples and limitations.

Continue reading

More articles

View all