All templates
Flowchart template

Saga pattern: distributed transaction

Choreography-based saga with compensating transactions on failure.

A saga is a distributed transaction that works when ACID is not an option. Instead of locking rows across databases, it coordinates a sequence of local transactions and, if any step fails, executes compensating transactions to undo the damage. This template shows the happy path (order → reserve inventory → payment → shipment) alongside every failure scenario and what gets undone.

Sagas are the backbone of reliable microservices. Without them, a payment failure that reserves inventory leaves your data in a state nobody can explain. With them, you have an explicit machine that can be tested, monitored, and debugged.

When to use this template

  • Designing microservice workflows — before writing a single line of code, map the saga so your team agrees on what happens when payment fails, inventory runs out, or shipping cannot find a carrier.
  • Incident post-mortems — "We charged the customer but never shipped" means a saga step failed and its compensation did not run. Use the diagram to trace which step and design the fix.
  • New engineer onboarding — sagas are hard to understand from code. Show the template first so they see the shape of the problem before diving into event handlers and compensations.

How to adapt it

Start by naming each step in your own business process — reserving stock, charging a card, sending an email confirmation, updating a warehouse system. Then add the compensations:

  • Insert a timeout decision after each operation — if it takes too long, assume failure and run compensations.
  • Add retry logic before compensation: attempt the step up to 3 times with exponential backoff before giving up and undoing.
  • Replace the generic "shipment created" with your actual carrier integration and show what happens if the label API is down.

Visual edits regenerate clean Mermaid code, so you can iterate on your saga in the editor and version the result in your architecture docs or decision log.

Mermaid code

Copy it anywhere Mermaid is supported — GitHub, Notion, or your docs.

flowchart TD
    A[Order placed] --> B[Reserve inventory]
    B --> C{Reserved?}
    C -->|No| D[Return error]
    C -->|Yes| E[Process payment]
    E --> F{Payment OK?}
    F -->|No| G[Release inventory]
    G --> D
    F -->|Yes| H[Create shipment]
    H --> I{Shipment created?}
    I -->|No| J[Refund payment]
    J --> G
    I -->|Yes| K[Order complete]

Frequently asked questions

What is a saga pattern distributed transaction?
A saga is a sequence of local transactions, each updating one service's data, chained together so that if any step fails, a series of compensating transactions undo the previous steps. Unlike a database transaction, a saga cannot lock rows across services — instead it explicitly models and executes compensations (refund, release inventory) to maintain data consistency across service boundaries.
What is the difference between choreography and orchestration in sagas?
Choreography means each service listens for events from others and triggers its own compensations — knowledge is distributed, making failures harder to debug. Orchestration means a central saga coordinator tells each service what to do and which compensations to run on failure — easier to follow and test. This template shows a choreography; add a Coordinator participant for an orchestration version.
Why are sagas necessary in microservices?
Microservices cannot use traditional database transactions spanning multiple databases — each service owns its data. A saga acknowledges this reality by explicitly modeling each step and its undo operation, so your code and team are never surprised when a failure leaves one service in an inconsistent state. Sagas make the hard parts visible instead of hidden.
How do I extend this for timeout and retry logic?
After each decision diamond, add another: "Timeout?" — if yes, retry the operation up to N times before triggering compensations. Insert a counter or backoff strategy to prevent cascading retries. For idempotency, mark the central order ID so that retried operations do not double-charge or double-ship. The visual editor supports nested diamonds without syntax friction.

Related templates