Cloud Native Patternsintermediate8 min

Choreography

Let each service react to events on its own instead of taking orders from a central conductor.

Think about how a dinner party actually runs. Nobody stands in the kitchen barking "now chop the onions, now you pour the wine, now you set the table." Instead each person watches what's happening and reacts: the smell of garlic tells the wine-pourer it's nearly time, an empty plate tells someone to clear it. There's no conductor — just people responding to signals. That's choreography.

The problem

When a business process spans several services — say, processing an order across inventory, payment, and shipping — something has to drive the steps. The obvious move is a central orchestrator: one service that calls inventory, waits, calls payment, waits, calls shipping. It works, but now every step depends on that one coordinator. It becomes a bottleneck, a single point of failure, and a place where the logic for every workflow piles up. Each service also ends up tightly coupled to the orchestrator's view of the world, so changing one step often means redeploying the brain in the middle.

Step through one order below. Partway through, the orchestrator goes down; predict what happens to the order before you look.

How it works

In choreography there is no central brain. Each service does its piece of work, then publishes an event announcing what it did — OrderPlaced, PaymentCaptured, OrderShipped. Other services subscribe to the events they care about and react. The order service emits OrderPlaced; inventory hears it, reserves stock, and emits StockReserved; payment hears that and charges the card; shipping reacts to PaymentCaptured. The workflow emerges from this chain of reactions, usually over a pub/sub bus or message broker.

Step through an order below, then a new request from marketing: send a thank-you email when an order ships. Predict what has to change before you look. Flip to Orchestrator at any step to see the same moment with a central coordinator, and stay for the last step: a stuck order.

Tip

Emit facts, not commands. A good choreography event says what happened (PaymentCaptured) rather than what to do next (StartShipping). Facts let new consumers join later without the publisher knowing about them, while commands quietly recreate the central-coordinator coupling you were trying to escape.

Check yourself

Your choreographed order flow works. Finance now wants every captured payment copied into its ledger. What's the choreography way to add that?

The catch: nobody owns the flow

Choreography's strength is also its weakness. The workflow isn't written down anywhere: it's the sum of every service's subscriptions. That's what made the email service free to add, and it's what makes the stuck order in the scene so uncomfortable. When order #1043 stalls, no service can say where it is, because no service knows the whole sequence. You rebuild the story from logs, one service at a time.

Teams that run choreography at scale buy that visibility back on purpose. Every event carries a correlation ID, such as the order number, so one search finds every event and log line for an order, and distributed tracing stitches them into a single timeline. Many keep an event catalog listing who publishes and who subscribes to each event. Some add a small observer that watches the stream and flags orders that stop moving: a read-only view of the flow, without taking control of it.

Watch out

Watch for the flow you can no longer see. As subscriptions pile up, simple questions get hard: what happens after PaymentCaptured? Could two services react to each other's events in an endless loop? Who breaks if OrderPlaced changes shape? If you can't answer from a diagram you trust, add tracing and an event catalog before adding more services, or move the core of the flow to an orchestrator.

Check yourself

Orders occasionally stall halfway through your choreographed flow, and no service logs an error. What would most help you find where they stop?

When to use it

Choreography is a great fit when the workflow is simple and fairly stable, when you want services to stay loosely coupled and scale independently, and when you're already building on event-driven architecture. It's the natural coordination style for a saga that values autonomy over central control, and it pairs well with competing consumers for scaling each reaction.

Where it hurts is visibility, as the stuck order showed. For complex workflows with lots of branching or compensation, or when you need one place to monitor and reason about the whole thing, orchestration is usually the kinder choice. Many systems mix the two: an orchestrator drives the core flow, and events tell everyone else what happened.

Key takeaways

  • Choreography spreads workflow logic across services: each one reacts to events and emits its own, with no central coordinator.
  • It keeps services loosely coupled and lets them scale and deploy independently — the opposite of an orchestrator everyone depends on.
  • The flip side is that the end-to-end flow is implicit. No single place tells you what the whole process does.
  • Events should be facts about what happened, and consumers must be idempotent because events get redelivered.
  • Choreography shines for simple, stable flows; reach for orchestration when the workflow is complex or needs central monitoring.

Keep going