Lesson 63 of 129
Choreography vs Orchestration
A business process such as placing an order touches several services. Something must decide which step runs next and what happens on failure. With choreography, there is no central coordinator: each service reacts to events and emits its own. With orchestration, a dedicated component, the orchestrator, tells each service what to do and tracks the state of the process.
Choreography
Each service subscribes to events from others and publishes events describing what it did. The workflow exists only as the sum of these reactions.
sequenceDiagram
participant O as Order
participant B as Broker
participant P as Payment
participant I as Inventory
participant S as Shipping
O->>B: OrderPlaced
B->>P: OrderPlaced
P->>B: PaymentCompleted
B->>I: PaymentCompleted
I->>B: StockReserved
B->>S: StockReserved
S->>B: ShipmentScheduledFailures are handled by publishing further events. If the payment succeeds but stock reservation fails, Inventory publishes StockReservationFailed, and Payment consumes it and refunds the customer, then publishes PaymentRefunded, which Order consumes to mark the order as cancelled. Each service therefore needs to know which foreign events require it to undo its own work.
sequenceDiagram
participant O as Order
participant B as Broker
participant P as Payment
participant I as Inventory
O->>B: OrderPlaced
B->>P: OrderPlaced
P->>B: PaymentCompleted
B->>I: PaymentCompleted
I->>B: StockReservationFailed
B->>P: StockReservationFailed
P->>B: PaymentRefunded
B->>O: PaymentRefundedProperties:
- No single point of coordination or failure beyond the broker.
- Services stay loosely coupled: the payment service does not know shipping exists.
- Adding a new reaction (for example, a loyalty service consuming
OrderPlaced) requires no change to existing services.
Drawbacks:
- The process definition is spread across services. Answering "what happens after an order is placed?" requires reading every consumer.
- Cyclic dependencies between services can form without anyone noticing. For example, if Inventory reacts to
PriceChangedby publishingStockAdjusted, and Pricing reacts toStockAdjustedby publishingPriceChanged, the two services can trigger each other indefinitely. - Tracking the state of one process instance requires correlation IDs and aggregation of events (see distributed tracing).
- Failure handling and compensation logic is distributed.
Orchestration
The orchestrator holds the process definition. It sends commands to services (synchronously or through messages), receives replies, and decides the next step or compensation.
sequenceDiagram
participant Or as Orchestrator
participant P as Payment
participant I as Inventory
participant S as Shipping
Or->>P: ChargeCustomer
P-->>Or: Charged
Or->>I: ReserveStock
I-->>Or: Reserved
Or->>S: ScheduleShipment
S-->>Or: ScheduledThe orchestrator persists the state of each process instance (for example PaymentPending, StockPending, ShipmentPending, Completed, Compensating, Cancelled) after every step. On a failure at step k, it issues compensating commands for the completed steps k-1 down to 1 in reverse order, such as RefundCustomer after ReserveStock fails. Commands and replies are correlated by a process instance ID. Because commands may be delivered more than once after a retry, participants must handle duplicates (see idempotent consumers).
Properties:
- The workflow is explicit in one place, with a defined state per instance.
- Timeouts, retries, and compensation are handled centrally.
- Participants are simple: they execute a command and reply.
Drawbacks:
- The orchestrator can become a bottleneck and must itself be highly available and durable.
- Business logic can leak into the orchestrator, turning participants into thin CRUD wrappers.
- Participants depend on the orchestrator's command format, which is a stronger coupling than reacting to a fact.
Comparison
| Aspect | Choreography | Orchestration |
|---|---|---|
| Control flow | Distributed, implicit | Central, explicit |
| Coupling | Low, event-based | Orchestrator knows all participants |
| Visibility of process state | Hard | Easy |
| Adding a step | Add a subscriber | Change the orchestrator |
| Failure handling | Each service compensates on events | Orchestrator drives compensation |
| Risk | Hidden cycles, hard to debug | Bottleneck, logic centralization |
| Suited for | Few steps, simple flows | Many steps, branching, long-running |
Workflow engines
An orchestrator that survives crashes must persist its state and resume timers. Building this manually is error-prone, so durable workflow engines exist:
- Temporal and its predecessor Cadence run workflow code as deterministic functions whose progress is recorded in an event history and replayed after a failure.
- AWS Step Functions define workflows as state machines in a JSON-based language.
- Camunda and similar engines execute BPMN process models.
They provide persisted state, timers, retries with backoff, and visibility into each instance.
In Temporal, workflow code must be deterministic, because recovery re-runs the code and matches each step against the recorded history. Non-deterministic work (network calls, random numbers, the current time) is performed in separate activities, whose results are recorded in the history and returned to the workflow on replay rather than executed again. Activities can run more than once, so they must be idempotent or protected by an idempotency key.
Orchestrator or process manager inside a service
An orchestrator does not have to be a shared platform component. It can be a part of the service that owns the process, such as the Order service running its own order-placement state machine. This limits the leakage of business logic into a central component and keeps ownership with one team. The orchestrator then coordinates the participants but does not contain their domain rules.
Choosing
- Use choreography for short flows with few participants, and for notifying interested parties of facts (for example, "OrderPlaced" consumed by analytics and email).
- Use orchestration when the flow has more than a few steps, branches, deadlines, or requires compensation in a defined order. See saga pattern.
- The approaches combine: an orchestrator coordinates the order saga and also publishes domain events that other services consume by choreography.
For the underlying messaging model see event-driven architecture.
Interview questions
- What is the main risk of choreography as flows grow? The process logic is scattered, so understanding, changing, and debugging it requires tracing events across many services, and cyclic event dependencies can appear.
- What is the main risk of orchestration? The orchestrator concentrates knowledge of the process and can become a single point of failure or a place where domain logic accumulates. It must be durable and replicated.
- Does orchestration require synchronous calls? No. An orchestrator can send commands over a broker and receive reply messages; the distinction concerns who controls the flow, not the transport.
- How does a workflow engine recover after a crash? It persists progress (state or an event history) and resumes from the last recorded step, re-executing or replaying the workflow definition.
