Problem
Distributed transactions with two-phase commit are impractical across independent services and databases. Without them, a failure partway through a business process leaves data inconsistent across services.
Coordinate multi-service business transactions through a sequence of local transactions and compensating actions.
Distributed transactions with two-phase commit are impractical across independent services and databases. Without them, a failure partway through a business process leaves data inconsistent across services.
A saga replaces one large atomic transaction with a chain of smaller ones, accepting temporary inconsistency in exchange for autonomy and availability. Correctness comes from compensations and careful state tracking.
In orchestration, a coordinator sends a command to the first service, waits for its outcome, and then commands the next. Each service commits its local transaction and replies. If a step fails, the orchestrator issues compensating commands for completed steps in reverse order, such as refunding a payment or releasing reserved stock. In choreography, services publish events and others subscribe, with failure events triggering compensations. Saga state is persisted so processing can resume after crashes, and steps use idempotency keys to tolerate redelivery.
# Orchestrated order saga
saga: place-order
steps:
- name: reserve-stock
action: inventory.reserve
compensation: inventory.release
- name: charge-payment
action: payments.charge
compensation: payments.refund
- name: create-shipment
action: shipping.create
compensation: shipping.cancel
onFailure: compensate-reverse
timeout: 5m
Teams adopt this approach when a business process spans multiple services with separate data stores; two-phase commit is unavailable or too costly. It is a poor fit when a single database transaction can cover the whole operation, or when steps cannot be compensated and intermediate states are unacceptable. The central tensions are choreography flexibility vs orchestration clarity; isolation vs availability; compensation completeness vs implementation effort. The main benefits are that it delivers: avoids distributed locks and two-phase commit; services remain autonomous and loosely coupled; explicit handling of failure paths; supports long-running workflows. The main costs to budget for are: intermediate states are visible to other users; compensations are hard to design correctly; complex debugging across services; requires idempotent steps and reliable messaging. Governance typically looks like this: each saga has a named owner and documented compensation semantics. Expect adoption cost to be high: workflow state, messaging, and compensations, and a best fit for medium to large teams with service-per-database architectures. Critics point out that lack of isolation permits anomalies that are hard to reason about, and that choreographed sagas become tangled and difficult to understand as steps grow. Treat these concerns as design inputs, and revisit the decision as traffic, team size, and failure history change.