How it works
Split the operation along transaction boundaries. For a booking, the inventory service creates a seat hold, the payment service authorizes payment, and the inventory service confirms the reservation. Each service commits its own changes locally.
Define the success path and the compensation for each completed step. Releasing a hold compensates for reserving inventory; voiding an authorization compensates for authorizing payment. Compensation is a new business action, not a database rollback, and it may not restore the exact original state.
Choose orchestration or choreography. An orchestrator durably records workflow progress and sends commands to participants. With choreography, services react to events and publish subsequent events; the workflow is spread across their handlers rather than controlled by one coordinator.
Make progress recoverable. Persist workflow state, step identifiers, results, and deadlines so a crash does not lose the next action. When a database update must produce a message, use a transactional outbox or equivalent reliable handoff; consumers must still tolerate duplicate delivery.
Treat timeouts as unknown outcomes, not proof of failure. If a payment call times out, query its status or retry using the same idempotency key before deciding what to do. Use step-specific idempotency keys and conditional state transitions to handle retries, duplicate messages, and late responses.
Protect local invariants while the saga is incomplete. An atomic seat hold prevents two bookings from owning the same seat; the saga alone does not. If compensation keeps failing, preserve a pending-recovery state, retry with backoff, and escalate for reconciliation or manual repair.
A worked example
A seat hold expires while payment is uncertain
A ticket costs $120, and the inventory service creates a five-minute hold for booking B42. An orchestrator records the hold, then requests payment authorization with idempotency key B42-authorize. The request times out, so the booking remains pending rather than failed. After recovery, the orchestrator queries the provider and learns that authorization succeeded. It then asks inventory to confirm the seat, conditional on B42 still owning an unexpired hold. The hold has expired, so confirmation fails; another customer may already own the seat. The saga voids the authorization using B42-void. If that request also times out, it durably tracks compensation as pending and reconciles until the outcome is known.
Trade-offs to say out loud
- Independent commits instead of global atomicity
- Services can commit without a shared distributed transaction, but users and other workflows may observe intermediate states.
- No automatic isolation
- Concurrent sagas can interfere, so inventory, balances, and ownership still need local transactions, reservations, or conditional updates.
- Compensation has business limits
- A refund can offset a charge, but it cannot erase fees, undo a delivered message, or reverse food preparation.
- Orchestration versus choreography
- Orchestration makes progress and recovery easier to inspect but adds a coordinator to operate, while choreography reduces central control but makes end-to-end behavior harder to trace.
- Recovery becomes application logic
- Durable timers, idempotency records, retry limits, compensation failures, and reconciliation add implementation and operational cost.
- Completion latency can vary
- Slow participants and retries may leave operations pending for minutes or longer, requiring explicit user-visible status rather than a premature success or failure.
When to reach for it
- A business operation spans independently owned databases or external APIs that cannot participate in one local transaction.
- The question includes booking and payment, restaurant acceptance and payment, or another workflow where partial success requires a business response.
- Steps can take long enough that holding database locks across the entire operation is impractical.
- The product can tolerate explicit pending states, and failed operations have meaningful compensations or a defined recovery process.
How to bring it up in the interview
- Start with the invariant and transaction boundaries: explain what must remain atomic locally before proposing a saga across services.
- Draw the forward steps alongside their compensations, and identify irreversible steps that should be delayed or handled through a different recovery policy.
- Choose orchestration or choreography explicitly; defend the choice using workflow complexity, ownership, and the need to inspect stuck operations.
- Walk through a crash after a remote side effect but before its response is recorded; interviewers will probe idempotency keys, status lookup, and durable recovery.
- Explain late-success and cancellation races, including which conditional transition wins and how failed compensation reaches reconciliation.
Common mistakes
- Calling a saga an ACID transaction or claiming that it provides isolation across services.
- Assuming every action has an exact inverse, or that compensating actions cannot fail.
- Treating a timeout as a definite failure and starting compensation while the original operation may still complete.
- Keeping workflow progress only in memory or updating state and publishing a message through an unreliable dual write.
- Using the saga to prevent double booking instead of enforcing inventory ownership atomically within the inventory service.
Where it comes up
Interview questions where saga pattern is part of a strong answer, and why.
- Design a ticket booking system like TicketmasterSeat holds, payment authorization, and booking confirmation need coordinated recovery when payment succeeds but inventory confirmation fails.
- Design a food delivery app like DoorDashRestaurant acceptance, payment, and courier assignment form a cross-service order lifecycle with partial failures and limited compensation options.
- Design a hotel booking systemThe workflow must coordinate date-range inventory holds with payment outcomes while handling expiration, late success, and compensation.
Questions people ask
What is the difference between the saga pattern and two-phase commit?
Two-phase commit coordinates an atomic commit decision across participating resources and can leave prepared participants waiting during failures. A saga commits each local transaction independently and handles later failures with retries or compensations. Sagas allow visible intermediate states and do not provide global transaction isolation.
What is orchestration versus choreography in a microservice saga?
In orchestration, a durable coordinator tracks progress and tells participants which step to execute. In choreography, services react to events and emit events that trigger subsequent steps. Both need retry-safe handlers and reliable messaging; choreography does not remove the need to understand and monitor the overall workflow.
How does a saga roll back a failed transaction?
It does not roll back already committed transactions in the database sense. It runs compensating business actions, such as releasing inventory or issuing a refund, usually in reverse dependency order. Those actions can fail or have uncertain outcomes, so the workflow needs durable recovery and sometimes manual intervention.