AlgoInsight

System Design

Orchestration vs. Choreography: Coordinating Microservices at Scale

Most distributed systems don't fail because the services are bad - they fail because the services don't coordinate. There are two ways to solve that: one central brain, or many independent reactors. Here's the full trade-off, the tools, and what Netflix, Uber, and Amazon actually use.

By Admin2026-07-1616 min readorchestrationchoreographymicroservicessaga-patternevent-drivensystem-design

Here's an uncomfortable truth about distributed systems: most of them don't fail because of poor design - they fail because of poor coordination. The individual services are usually well-built. The order service works, the payment service works, the inventory service works. Where things break down is in how they communicate, react, and hand off work to each other. Coordination - not the services themselves - is the hard part, and it's the core challenge the Saga pattern addresses. But the Saga leaves one critical question open: who decides what happens next? There are two fundamentally different answers - orchestration and choreography - and choosing between them is one of the most consequential decisions in distributed system design. This post is the full comparison, including what the biggest systems actually choose.

(This builds on the saga pattern and eventual consistency posts - here we go deep on the coordination strategy the saga needs.)

Recap: the Saga needs a coordination strategy

Quick recap. The Saga pattern breaks a large distributed transaction into independent steps - each committing on its own, and compensating on failure - so you get transaction-like behavior across microservices without a global lock or distributed rollback. That's the structure. But a crucial question remains unanswered:

Who decides what happens next? Who tells the payment service to run after the order is created? Who triggers the refund when inventory fails? The Saga defines that steps happen and that compensation occurs - but not who coordinates the sequence. The answer depends entirely on which coordination strategy you choose. And there are exactly two.

Approach 1: Orchestration - one brain controls everything

In orchestration, a single central service - the orchestrator - controls the entire flow. It's the conductor of the orchestra: it knows the full sequence of steps, tells each service what to do next, and handles the compensation logic when something fails.

Order created? The orchestrator says "payment service, go." Payment done? The orchestrator says "inventory service, go." Inventory fails? The orchestrator triggers the compensation - "payment service, refund." Every transition is directed by the orchestrator. The services themselves are relatively passive participants; they do what the orchestrator tells them and report back.

The advantages are about visibility and control:

But there's a real cost: one brain controls everything. That central orchestrator is a single point of failure (if it goes down, coordination stops) and a potential bottleneck as the system grows (every transaction flows through it). You've centralized the coordination, which gives you clarity - but also a chokepoint.

Approach 2: Choreography - no central controller

In choreography, there is no central coordinator at all. Instead, each service listens for events and reacts independently. It's a dance where every dancer knows their own moves and responds to what the others do - no conductor.

When the order service completes, it emits an event ("order created"). The payment service, listening for that event, hears it and processes the payment - then emits its own event. When an inventory update fails, a refund service, listening for that failure event, hears it and triggers a refund automatically. No service tells another what to do - they're all just reacting to what happened. The coordination logic is distributed across the services, connected by a stream of events (flowing through a message broker - see the message queues material).

The advantages are about scalability and flexibility:

But choreography has its own cost: it's harder to trace. The flow is spread across multiple services with no single place to see the full picture. When you ask "where is this transaction right now, and why did it fail?", there's no orchestrator to consult - you have to reconstruct the flow from events scattered across many services. What you gained in decoupling, you paid for in observability.

The core trade-off: control vs. flexibility

Strip it down, and the fundamental trade-off is control vs. flexibility:

Neither is "better." Orchestration trades scalability and decoupling for clarity and control. Choreography trades clarity and control for scalability and decoupling. The right choice depends on what your particular flow needs more: to be understood and controlled, or to be decoupled and scaled.

graph TD
    Q{What does this flow need most?} --> A{Complex, critical,<br/>needs strict ordering<br/>& visibility?}
    Q --> B{Simple, high-volume,<br/>loosely coupled,<br/>event-driven?}
    A -->|Yes| ORCH[Orchestration<br/>central coordinator<br/>control & traceability]
    B -->|Yes| CHOR[Choreography<br/>event-driven reactors<br/>scale & decoupling]
This decision diagram frames the choice by what the flow needs most. If the flow is complex and critical, needs strict ordering, and requires visibility for debugging and monitoring, choose orchestration - a central coordinator giving control and traceability. If the flow is simple, high-volume, loosely coupled, and suits event-driven design, choose choreography - event-driven reactors giving scale and decoupling. The decision comes down to whether the flow most needs control or flexibility.

When to use orchestration

Reach for orchestration when:

Common orchestration tools include Temporal, Camunda, AWS Step Functions, and Netflix Conductor - workflow engines built specifically to run and monitor orchestrated flows, handling state, retries, and compensation for you.

When to use choreography

Reach for choreography when:

Common choreography tools include Apache Kafka, RabbitMQ, AWS EventBridge, and SNS/SQS - messaging and event-streaming systems that carry the events services publish and subscribe to. (These are the same messaging backbones covered in the message queues and Kafka material.)

What do big systems actually choose?

Here's the question everyone really wants answered - and the honest answer surprises people: most large-scale systems use a hybrid approach. They don't pick one strategy for everything; they choose per flow, based on what that flow needs.

The pattern that emerges again and again:

Netflix, Uber, and Amazon all use combinations of both, choosing per use case based on criticality and scale requirements. The mature answer to "orchestration or choreography?" isn't one or the other - it's "which, for this flow?" Critical and complex → orchestrate. High-volume and simple → choreograph. A large system is a patchwork of both, each applied where it fits.

graph TD
    subgraph CRIT["Critical flows → Orchestration"]
    OR[Orchestrator] --> P1[Order] & P2[Payment] & P3[Inventory]
    end
    subgraph HV["High-volume flows → Choreography"]
    E[Event] --> N1[Notifications] & N2[Analytics] & N3[Logging]
    end
This diagram shows the hybrid approach used by large systems. Critical flows like order, payment, and inventory are handled by orchestration, with a central orchestrator directing them for control and traceability. High-volume, less-critical flows like notifications, analytics, and logging are handled by choreography, where services independently react to events for scale and decoupling. Big systems use both, matching the strategy to each flow's criticality and volume.

Tip: The senior-level takeaway: don't ask "orchestration or choreography?" - ask "orchestration or choreography for this specific flow?" The instinct to pick one strategy and apply it everywhere is a beginner's mistake. Real systems match the strategy to the flow: the payment path (critical, needs traceability) gets orchestration; the notification fan-out (high-volume, loosely coupled, non-critical) gets choreography. Recognizing that the two coexist in one system - and knowing which flows call for which - is exactly the judgment that distinguishes someone who's read about these patterns from someone who's built with them.

Important: The framing to carry away: distributed systems fail on coordination, not on individual service quality. Orchestration and choreography are the two ways to coordinate - one centralizes the decision-making (a conductor), the other distributes it (a dance of reactors). Centralizing buys you clarity and control at the cost of a chokepoint; distributing buys you scale and decoupling at the cost of visibility. Getting coordination right - choosing the right strategy per flow - is often what determines whether a distributed system is reliable or fragile.

Interview: Orchestration vs. choreography is a favorite senior system design question. The strong answer names the trade-off crisply: orchestration = central coordinator, giving control and traceability but a single point of coordination; choreography = event-driven services reacting independently, giving scalability and decoupling but harder observability. Then apply it: orchestration for complex, critical, strictly-ordered flows (with tools like Temporal or Step Functions); choreography for simple, high-volume, loosely-coupled flows (with Kafka or SNS/SQS). The flourish that signals real experience: noting that big systems use a hybrid - orchestrating critical flows (payments) and choreographing high-volume ones (notifications) - because the right question is "which per flow," not "which overall."

A worked example: one checkout, both strategies

To make the hybrid concrete, walk through a single e-commerce checkout and watch both strategies operate in the same transaction.

The user clicks "Place Order." The critical core - create order, charge payment, reserve inventory - runs under orchestration. A central orchestrator directs it: create the order, then charge payment, then reserve inventory, and if any step fails, it fires the exact compensations (refund, cancel) in order. This flow must be correct, strictly ordered, and traceable - if a customer's money is involved, you need to see precisely what happened. So it's orchestrated.

But the moment the order is confirmed, a burst of secondary actions needs to happen: send an order-confirmation email, send an SMS, update the recommendation engine, log the event for analytics, notify the warehouse dashboard, update loyalty points. These are high-volume, non-critical, and independent - none of them needs to happen in a strict order, and if the analytics update is a few seconds late, nobody cares. So the order service simply emits an "order confirmed" event, and all those secondary services choreograph - each listens and reacts independently. Adding a new one later (say, a fraud-check logger) means adding a new listener, not touching the orchestrator.

One checkout, two coordination strategies: orchestration for the money-critical core, choreography for the high-volume fan-out. This is exactly what a real large-scale checkout looks like, and it's why the "which one?" framing is wrong - a single transaction can use both, applied to the parts that suit each. The critical path is controlled; the fan-out is decoupled.

Common mistakes in choosing

A few mistakes show up repeatedly when teams choose a coordination strategy, and knowing them sharpens the decision:

The through-line: match the strategy to each flow's real needs, use both where appropriate, and account for the cost of each (a bottleneck for orchestration, lost visibility for choreography) rather than pretending the trade-off doesn't exist.

The bottom line

Distributed systems fail on coordination, not design - and the Saga pattern needs a coordination strategy to answer "who decides what happens next?" There are two. Orchestration uses a central orchestrator that directs every step and compensation - giving centralized visibility and control (easy to understand and debug), at the cost of a single point of coordination that can become a failure point and bottleneck. Choreography has no coordinator; services react independently to events - giving decentralization, scalability, and flexibility (add a step by adding a listener), at the cost of observability (the flow is scattered, hard to trace).

The core trade-off is control vs. flexibility. Use orchestration for complex, critical, strictly-ordered flows needing visibility (Temporal, Camunda, Step Functions, Conductor); use choreography for simple, high-volume, loosely-coupled, event-driven flows (Kafka, RabbitMQ, EventBridge, SNS/SQS). And what do the biggest systems actually do? Both - orchestrating critical flows and choreographing high-volume ones, matching the strategy to each flow's criticality and scale. The mature question is never "which one," but "which one, for this flow." We cover coordination strategies, the saga pattern, and distributed system design across System Design Fundamentals.


Go deeper

More articles