Saga

A saga is a business process split into a sequence of local transactions, each committing independently in one system, with a defined way to undo the earlier ones if a later one fails. It is the usual answer when work spans systems that cannot share a transaction.

The idea is older than microservices. Garcia-Molina and Salem introduced it in 1987 for long-lived transactions, whose problem was locking: “to make a transaction atomic, the system usually locks the objects accessed by the transaction until it commits,” and “as a consequence, other transactions wishing to access the LLT’s objects suffer a long locking delay.” Their definition is that a long-lived transaction “is a saga if it can be written as a sequence of transactions that can be interleaved with other transactions,” and the system “guarantees that either all the transactions in a saga are successfully completed or compensating transactions are run to amend a partial execution.”

Read the guarantee carefully

That guarantee is narrower than atomicity, and the gap is where most misuse lives. What is promised is that one of two sequences runs: every step, or some prefix of the steps followed by their compensations. Nothing is promised about who observed the state in between.

The original authors say so in a parenthesis that deserves more attention than it gets:

Note that other transactions might see the effects of a partial saga execution. When a compensating transaction Cj is run, no effort is made to notify or abort transactions that might have seen the results of Tj before they were compensated for by Cj.

So a saga is not a distributed rollback. A rollback makes it as though nothing happened; a saga makes a correcting entry and leaves every reader of the intermediate state untouched. If a customer saw “reserved,” if an operator acted on it, if a report counted it, those things occurred and compensation does not unmake them.

Current pattern documentation puts the same fact operationally — “data can’t be rolled back because saga participants commit changes to their respective databases” — and names what the missing isolation exposes you to: lost updates, “dirty reads,” and “fuzzy, or nonrepeatable, reads.” Published countermeasures are all application-level: a semantic lock marking a record as in-flight, commutative updates that can be applied in any order, reordering so risky reads happen after the point of no return, rereading values before acting on them, and keeping a version log per record. Each is work you take on; none is provided by the pattern.

When the shape fits

The paper states the condition, and it is worth testing a process against it before adopting the pattern. A saga suits work that is “a sequence of relatively independent steps, where each step does not have to observe the same consistent database state.” The authors justify this from the physical world: “in reality, one does not physically lock the warehouse until a purchase order is fully processed.”

The question to ask, then, is whether a later step’s correctness depends on nothing having changed since an earlier one. If it does, a saga is not a cheaper way to get what a transaction gave you — it is a different mechanism that does not provide it, and the resulting anomalies will be found by customers. If it does not, the pattern is a good fit and the design work is mostly about compensation and visibility.

Three kinds of step

A useful classification splits a saga’s steps by what can be done when something later goes wrong.

  • Compensable steps “can be undone or compensated for by other transactions with the opposite effect.”
  • The pivot step is the one where “pivot transactions serve as the point of no return in the saga.” After it succeeds, “compensable transactions are no longer relevant” — reversal has stopped being available.
  • Retryable steps “follow the pivot transaction,” are “idempotent,” and let the saga reach its final state by repetition rather than reversal.

Locating the pivot in a real process is the highest-value part of this design. The candidates are usually physical or external — goods left the dock, an email reached a customer, funds settled, a filing was submitted — but physical irreversibility is not the test. Compensation is new business work rather than a restoration, so a permitted refund compensates a settled payment and an authorised return compensates a shipment. A step is a genuine pivot when your workflow’s rules admit no acceptable reversal, which is a business judgment made per process rather than a property of the action.

Two moves follow from knowing where it is: push the irreversible step as late as the business allows, and treat everything after it as work that must eventually complete rather than work that might be abandoned.

That second move is the paper’s other recovery direction. “When a failure interrupts a saga, there are two choices: compensate for the executed transactions, backward recovery, or execute the missing transactions, forward recovery,” with the honest caveat that “forward recovery may not be an option in all situations.” Backward recovery needs compensations; forward recovery needs save-points. Most real sagas use both, in different segments.

Where the coordination lives

Two implementation shapes are standard. In choreography, “services exchange events without a centralized controller” — each step publishes an event that triggers the next. In orchestration, “a centralized controller, or orchestrator, handles all the transactions and tells the participants which operation to perform.”

The documented trade-offs are about legibility rather than correctness. Choreography suits “simple workflows that have few services,” needs no extra component, and has no single point of failure; against it, the “workflow can be confusing when you add new steps,” it is “difficult to track which commands each saga participant responds to,” there is a risk of cyclic dependency, and integration testing requires every service running. Orchestration is “better suited for complex workflows,” avoids cycles, and gives a “clear separation of responsibilities”; against it, the coordination logic has to be built and the orchestrator “introduces a point of failure.”

For a process crossing departmental systems and subject to audit, I would take the orchestrator. The deciding question is not usually throughput but this one: when someone asks where order 4471 stopped, an orchestrator answers from one place, and a choreographed flow has to be reconstructed from the logs of six services.

What recovery depends on

One consequence is easy to miss until an incident. A database recovers from its log with no help from the application. A half-finished saga does not — the 1987 paper puts it directly: “to complete a running saga after a crash it is necessary to either complete the missing transactions or to run compensating transactions to abort the saga. In either case it is essential to have the required application code.”

So a saga state store is meaningless without a deployable application that understands it, and retiring the service that owned an orchestration does not release you from the sagas it left open. Pattern guidance adds the related caution that compensations themselves “might not always succeed, which can leave the system in an inconsistent state” — so a saga needs somewhere for stuck instances to go and someone whose job it is to resolve them.

Which is why a saga is a mechanism for coordinating work, never a proof that the work finished. Confirming that is a separate control: comparing the participating systems against each other, as reconciliation does. The wider design — how the intermediate states, the message delivery, and the business-completion check fit together across an enterprise estate — is worked through in Nothing Rolls Back, and the mechanics of reversal are in compensating transaction. What a saga gives up in exchange is described under two-phase commit. And note that giving up atomicity does not hand you convergence: eventual consistency holds only where propagation is durable, conflicts resolve by a stated rule, and something detects and repairs what was missed — a saga creates the need for those rather than supplying them.

References: Hector Garcia-Molina and Kenneth Salem, “Sagas,” Proceedings of the 1987 ACM SIGMOD International Conference on Management of Data, pp. 249–259; Microsoft Azure Architecture Center, Saga Design Pattern (documentation dated 2025-02-25).


Discover more from Insightful Data Lab

Subscribe to get the latest posts sent to your email.

Similar Posts

Questions, corrections, or additional insights?

This site uses Akismet to reduce spam. Learn how your comment data is processed.