Saga Choreography
A saga with no conductor — each service reacts to domain events and emits its own. A fit for EDI cycles where partners are autonomous, where Saga Orchestration would impose a centralised coordinator.
Problem
An EDI cycle ORDERS → ORDRSP → DESADV → INVOIC → REMADV spans several internal services (Procurement, Logistics, Billing, Treasury) that are autonomous and already decoupled by messaging. Imposing a centralised orchestrator adds a coupling point and a bottleneck: every step must signal completion to the orchestrator, which must decide the next step. Why not let each service react directly to the previous event?
Forces
- No central service. The saga lives in event interactions; no team owns the full workflow.
- Loose coupling. Each service only knows the events it consumes and emits, not the overall sequence.
- But the workflow hides itself. Understanding the end-to-end sequence requires reading the code of every service.
- Cycles are possible. If A reacts to B, B reacts to C and C reacts to A, an undetected loop can form.
Solution
Each domain service subscribes to relevant events and emits its own
in response. Compensations are triggered by inverse events
(OrderCancelled, ShipmentRecalled) that
each service consumes if it carried out the matching effect. No
service owns the full sequence; it emerges from composition.
[Buyer service] receives ORDERS from a partner
│
├─emit─► OrderAccepted(orderId=ORD789) ─► topic: orders
│
[Supplier service] consumes OrderAccepted
├─emit─► ORDRSP sent to EDI partner ─► topic: order-responses
│
[Logistics service] consumes OrderAccepted, prepares shipment
├─emit─► ShipmentDispatched(asn=ASN9001) ─► topic: shipments
├─send─► DESADV to partner
│
[Billing service] consumes ShipmentDispatched (+ time trigger)
├─emit─► InvoiceIssued(invoice=INV-7811) ─► topic: invoices
├─send─► INVOIC to partner
│
[Treasury service] consumes InvoiceIssued + ReceiptConfirmed
├─emit─► PaymentRemitted(amount=1240.00) ─► topic: payments
└─send─► REMADV to partner
Compensation = each service exposes a handler for the inverse events
(OrderCancelled, ShipmentRecalled, InvoiceCredited). EDI implementation
Concrete EDI case: the orchestration of a PO ↔ ASN ↔ INVOIC ↔ REMADV
cycle. The Buyer service receives a partner ORDERS,
validates it, publishes an OrderAccepted event on the
Kafka topic orders. The Supplier service
consumes, emits an ORDRSP and publishes OrderConfirmed.
The Logistics service consumes OrderAccepted,
prepares the shipment and publishes ShipmentDispatched
— it also emits the DESADV to the EDI partner. The Billing
service consumes ShipmentDispatched and emits the
INVOIC. The Treasury service waits for ReceiptConfirmed from the RECADV reception, triggers
payment and emits the REMADV. No component owns the full workflow;
it lives in the Kafka subscription graph.
Choreography vs Orchestration
The two Saga variants (Choreography, Orchestration) are complementary:
- Choreography fits 3-5 step workflows that are stable and well understood, in mature organisations carved into bounded contexts.
- Orchestration fits complex, changing workflows, or ones with fine conditional branches, where workflow readability trumps decoupling.
- Often both coexist: choreography between domains, orchestration inside a domain.
Anti-patterns
- Workflow hidden across 10 services. Without an event map, no one understands the cycle end-to-end after 18 months.
- Undetected loop. Service A produces X, B reacts by producing Y which causes A to produce X — the chain explodes.
- Partial compensations. A service forgets to
consume
OrderCancelled: the order remains cancelled in 4 services out of 5, leaving state inconsistent. - No transverse TraceId. Without a correlation identifier propagated in every event, incident investigation becomes a treasure hunt.
Related patterns
- Saga Orchestration — the variant with a central orchestrator.
- Process Manager — parent concept.
- Event Message — the natural message style for choreography.
- Correlation Identifier — indispensable for tracing the saga.
Sources
- Garcia-Molina H., Salem K. — Sagas, ACM SIGMOD 1987. dl.acm.org/doi/10.1145/38713.38742
- Richardson C. — Microservices Patterns, Manning 2018, chap. 4 "Managing transactions with sagas". microservices.io/patterns/data/saga.html
- Microsoft — Saga distributed transactions pattern. learn.microsoft.com — Saga
- Nygard M. — Release It!, Pragmatic Bookshelf 2018, on loose coupling and event patterns.