Saga (Long-running distributed transaction)
Problem
You have a business transaction that spans multiple services or databases (place order → charge payment → reserve inventory → send confirmation). Two-phase commit is too slow, too coupling, and often not available across service boundaries.
Context
Common in microservices architectures and long-running workflows. Any time your 'transaction' involves calls to 2+ independent systems that don't share a database, you're in Saga territory.
Solution
Break the transaction into a sequence of local transactions, each in its own service. Define a compensating action for each step (charge → refund, reserve → release). Execute steps in order; if any step fails, run compensating actions for all completed steps in reverse. Two flavors: choreography (each service publishes events) or orchestration (a central coordinator drives the flow).
Trade-offs
- No ACID — you get eventual consistency plus explicit compensation logic
- Compensating actions are semantically hard: refund isn't inverse of charge (fees), release inventory may not restore holds
- Debugging is hard — you have to trace an event chain across services
- Choreography = loose coupling but no single source of truth; orchestration = single point of coordination but tighter coupling
- Failures during compensation need their own retry + escalation policy
Failure modes
- Non-idempotent compensating actions run twice (retry) → double refund
- Compensating action itself fails → half-completed rollback; needs manual intervention
- Race between saga step and other transactions on the same entity → inconsistent state
- Saga coordinator becomes a hot service; if it goes down, all in-flight sagas stall
When to use
- Multi-service business transactions where 2PC is unavailable or too slow
- Long-running processes (hours to days) where holding transaction locks is not feasible
- You can define correct-enough compensating actions for every step
When NOT to use
- All entities are in the same database — use a plain DB transaction
- You cannot define a semantically correct compensating action (e.g., sending a physical letter)
- Very simple 2-step operations where the failure mode is trivial (retry, no need for saga)
Systems that use this pattern
Where this pattern gets applied on the platform — concrete usage context per system.