Glossary
Saga Pattern
A saga assembles one business process from several independently committed steps. It does not create a classic distributed ACID transaction, and compensation is not an automatic rollback.
Short definition
Each participant commits its own step and the process continues according to the result.
An order can be created, reserve inventory, start a payment, and finally become confirmed. Each step runs in its own local transaction and its result triggers the next step. Between steps, the system is in a valid but intermediate state such as PAYMENT_PENDING; neither the client nor an operator should mistake it for a completed outcome.
When a later step fails because of a business rule, the saga starts compensations for earlier completed steps. Releasing inventory, cancelling an order, and refunding are new domain operations with their own rules, not a reversal of time. They may also fail, run later, or require manual intervention.
Problem it solves
One process crosses several transaction boundaries.
A distributed system usually cannot wrap inventory, payment, shipping, and the order in one database transaction. A saga gives their local changes explicit order, state, and failure paths.
- creating an order, reserving inventory, and starting payment in separate services
- activating a customer account together with provisioning an external service
- a travel reservation composed of transport, accommodation, and payment
- a product return involving warehouse receipt, refund, and accounting entry
- a long import or approval workflow split into repeatable steps
Practical example and diagram
An order, inventory, and a failed payment
Order Service creates an order in the PENDING state. Inventory Service reserves items and replies with InventoryReserved. Payment Service attempts to authorise the payment. On success, the order becomes CONFIRMED and shipping may follow. If the bank declines payment, the workflow does not technically roll back previous databases.
Instead, it starts ReleaseInventory and changes the order to PAYMENT_FAILED or CANCELLED. Releasing stock may now require a different rule from the original reservation and can itself fail. The process therefore stores the attempt, reason, last successful step, and compensation state; an alert identifies a saga that exceeds its expected duration.
Text diagram and its alternative
Create Order
↓
Reserve Inventory
↓
Authorize Payment
├─ success → Confirm Order
└─ failed
↓
Compensation workflow
↓
Release Inventory
↓
Cancel Order
How it works
Forward steps and the compensation path
The sequence is the diagram’s textual alternative. A particular saga can have different ordering, parallel branches, and points beyond which complete compensation is no longer possible.
- Process instance creation The workflow receives a stable saga_id and stores its initial state. A repeated request must not create a second order or another instance of the same business process.
- Local transaction Each service checks its rules and atomically changes only its own data. After commit, it publishes the result or returns a response that determines the next step.
- Partial failure A timeout does not reveal whether the remote step completed. Coordination therefore first finds the state or safely repeats a command rather than automatically assuming failure.
- Compensation After a definitive business failure, cancellation operations follow for the steps that can and must be offset. Their order follows the domain and need not exactly reverse the forward steps.
- Final or intervention state The process ends as confirmed, cancelled, partly compensated, or requiring manual resolution. Every outcome must be traceable through the API, support tooling, and monitoring.
Two coordination variants
Choreography distributes decisions; orchestration centralises them.
Both approaches use local transactions and messages. The choice affects process readability, service coupling, and where its state is kept.
Choreography
Each service reacts to the preceding participant’s event and publishes its own result. There is no central coordinator; a simple flow needs little infrastructure, but with more branches the order and failure path can become scattered across many handlers.
Orchestration
A dedicated orchestrator stores process state, sends commands to participants, and chooses the next step from their replies. It makes a complex workflow clearer, but must not absorb each service’s internal domain rules or become an unavailable point with no recovery.
Saga state
A stable identifier, current step, version, attempts, and results allow continuation after a restart. The state should not exist only in process memory or an untraceable sequence of logs.
Reliable messages
The Outbox Pattern can atomically connect a participant’s local change with publishing its result. It does not make saga decisions by itself; it only reduces the risk that a committed step loses its follow-up message.
Isolation and concurrency
A saga provides no automatic isolation between two concurrent processes. State transitions, versions, reservations, constraints, or semantic locks must stop one saga from using a resource already changed by another.
Benefits and limitations
Controlled partial changes replace the convenience of automatic rollback.
Potential benefits
- coordination of a long process without one distributed database transaction
- each service retains its own data and local rules
- an outage in one step can be absorbed temporarily and retried safely later
- explicit state allows progress to be shown to a client and incidents traced by an operator
Limitations and common mistakes
- compensation may not restore the original world exactly; an email cannot be recalled and a refund’s cost may change
- a compensating operation can fail and needs its own retries, idempotence, and escalation
- choreography with many participants can hide the process in an event network and create cycles
- an orchestrator without durable state or high availability becomes a fragile point
- a saga without concurrency protection lets other transactions observe and change intermediate state
When it fits
For a genuine process spanning several independent commits.
Microservice architecture often creates transaction boundaries that make a saga useful, but microservices are not a prerequisite. The same pattern can apply when working with an external payment API or multiple modules that cannot share a commit. What matters is a long-running business process and the need to control partial outcomes.
A simple process over several tables in one database usually does not need a saga. A short local transaction provides stronger and simpler guarantees. A saga is also not a synonym for CQRS or Event Sourcing: it can be combined with them, but command/query separation and storing an event history solve different problems.
Before use, determine whether each forward step has an acceptable compensation. Some actions have a point of no return, such as a physically delivered parcel. Instead of pretending to return to the original state, the workflow then enters a new process such as a return, refund, or manual resolution.
Resilience and observability
Every step must be repeatable, measurable, and traceable.
A workflow is a production state machine. Relying on log order or on the broker delivering each message exactly once is insufficient.
- provide idempotence for commands, replies, and compensations through stable identifiers
- set a timeout, limited retry, and an unknown-outcome rule for each remote step
- store saga_id, correlation ID, current state, version, and decision history
- measure process duration, retry count, failed compensations, and instances awaiting intervention
- test a crash before and after every step’s commit, duplicates, reordering, and concurrent sagas
- design authorisation and audit for manual completion, skipping, or compensation
Common questions
A saga without the idea of global rollback
Is the Saga Pattern a distributed ACID transaction?
No. Individual local transactions commit independently, with no global atomicity or automatic isolation between steps. Workflow state, messages, and compensating operations maintain process consistency.
Does compensation always restore exactly the original state?
No. Compensation creates a new valid business state. It can release a reservation or refund a payment, but cannot undo a read email, elapsed time, or every external cost.
Is choreography or orchestration better?
It depends on flow complexity. Choreography may fit a few clear reactions; orchestration clarifies branching, timeouts, and compensations. Both variants need durable state and observability in the appropriate place.
What happens when compensation fails?
Store its state, retry it safely, and alert an operator after exceeding a limit. Some cases require a manual decision or a new repair process; they must not disappear into a log.
Does every saga need a message broker?
Not necessarily. Coordination can also use synchronous APIs and a durable workflow engine. Once it crosses network boundaries, however, it must handle timeouts, unknown outcomes, retries, and crash recovery regardless of transport.
How I design multi-step processes
I model intermediate state, failures, and compensation as part of the business flow.
For integration processes I define local boundaries, idempotent steps, expected timeouts, and a route to manual completion.