Where does the Mediator idea reappear at architecture scale, and what changes about the trade-offs when the colleagues are separate services instead of objects in one process?
answer
- Mediator is a scale-free topology
- Orchestration = mediator; choreography = observer
- Hub becomes runtime SPOF, not just churn hotspot
- Saga: persisted state, idempotency, compensation
- Smart endpoints, dumb pipes; one orchestrator per process
basics
~20 sThe same star topology appears as orchestrators, workflow/saga coordinators, message brokers, API gateways, and enterprise service buses. Across services the centralizer also becomes an availability, scaling, and ownership bottleneck — not just a code-cohesion problem.
solid answer
~50 sMediator is a topology, so it recurs at every scale: a UI controller coordinating widgets, a saga/workflow coordinator driving a multi-service business transaction (orchestration, as opposed to event-driven choreography), a message broker or enterprise service bus routing between systems, an API gateway or backend-for-frontend fronting many services. In-process, the cost of centralizing is mainly cohesion and churn. Across services three new costs appear. First, *availability*: the mediator sits on the critical path, so its outage stops all coordinated flows — you need redundancy, timeouts, retries with idempotency, and backpressure. Second, *state and failure semantics*: with no shared transaction, the coordinator must persist progress and drive compensations (saga), handle partial failure and duplicate delivery. Third, *organizational coupling*: the coordinator encodes rules owned by several teams, so it becomes a shared-ownership bottleneck — the "smart ESB" anti-pattern of business logic living in the pipes. The rule of thumb inverts: prefer smart endpoints and dumb pipes, and centralize only the coordination that genuinely spans domains.
go deeper
Recognize that the same 'everyone talks to one coordinator' shape shows up as message brokers and API gateways, not just in code.
Name orchestration vs choreography as the distributed echo of Mediator vs Observer and give one example of each.
Add the operational costs of a cross-service hub — availability, scaling, saga state, idempotency, compensation — and argue when each style fits.
Connect the GoF god-object liability to the ESB/central-orchestrator critique, reason about organizational ownership and release coupling, and set the guardrails (one orchestrator per process, declarative rules, smart endpoints/dumb pipes, SLOs and tracing).
## The pattern is really a topology Strip Mediator to its structure: *replace peer-to-peer links between N participants with links to one coordinator that owns the interaction rules*. That shape is scale-free, and you meet it repeatedly: | Scale | Mediator instance | Colleagues | |---|---|---| | Widgets in a dialog | dialog/controller | fields, buttons | | Objects in a module | GoF mediator class | domain objects | | Requests in an app | in-process dispatcher (request → handler) | handlers | | Business process | saga / workflow orchestrator | services | | Systems | message broker, ESB, integration hub | applications | | Edge | API gateway, backend-for-frontend | microservices | | Network | service mesh control plane | sidecars | Each trades many-to-many integration for a star, and each inherits the same liability: the hub can accumulate everyone's rules. ## Orchestration vs choreography The distributed restatement of "Mediator vs Observer": - **Orchestration (Mediator-like)**: a coordinator explicitly invokes participants in order — `reserveInventory`, then `chargeCard`, then `scheduleShipment`; on failure it runs compensations in reverse. The whole process is readable in one place; status is queryable; ordering is deterministic. - **Choreography (Observer-like)**: each service publishes events and reacts to others' events. No component owns the process; behaviour is emergent, participants are independently deployable, and the flow is discovered only by tracing. Neither is universally right. Orchestration wins when the process has many conditional branches, needs compensation, needs visibility ("where is order 123?"), or crosses domains that must be sequenced. Choreography wins when reactions are independent, teams must move without coordinating releases, and the fan-out is additive. ## What genuinely changes across a process boundary ### 1. Availability and blast radius In-process, the mediator cannot fail independently of its colleagues. Across services it can. It is on the critical path of every coordinated flow, so it needs redundancy, health checks, circuit breakers, timeouts, and graceful degradation. A single-instance orchestrator is a single point of failure for every process it drives. ### 2. Scaling and backpressure All traffic funnels through the hub, so it must scale horizontally — which usually means externalizing its state (workflow state in a database or the workflow engine's own store) so any instance can resume any process. It also needs backpressure and queueing, or it becomes the congestion point. ### 3. Failure semantics without transactions There is no distributed ACID transaction, so the coordinator must be a *saga*: persist each step, make calls idempotent (participants may see retries), define compensating actions for each completed step, and handle timeouts where the outcome is unknown. This is real state-machine engineering, not a `switch`. ### 4. Versioning and deployment coupling A change to any participant's contract may require the coordinator to be redeployed. Long-running processes may be in flight across versions, so the coordinator needs versioned process definitions. ### 5. Organizational ownership — the decisive one The in-process god-object problem becomes a *shared-ownership* problem. If the hub encodes rules owned by several teams, every team's change queues behind the hub team. This is the well-known critique of the enterprise service bus: business logic migrated into the integration layer until the bus became the bottleneck for the whole organization. The corrective slogan is **smart endpoints, dumb pipes** — routing/transport in the pipe, business rules in the services. ## How principals decide - Centralize the coordination that is genuinely *cross-domain* and needs visibility or compensation; leave intra-domain reactions to events. - Give each orchestrated process a clear owning team; if you cannot name one owner, that process probably should not be orchestrated centrally. - Prefer many small orchestrators (one per business process) over one platform orchestrator — the same "split by cohesion" rule as the in-process mediator. - Keep the hub declarative where possible (workflow definitions, routing rules) so participants' logic does not migrate into it. - Instrument the hub as a first-class service: SLOs, tracing across hops, and per-process state visibility — otherwise the readability benefit you bought is theoretical. ## The invariant At every scale the trade is the same: **centralizing an interaction makes it visible and changeable in one place, at the cost of creating a bottleneck**. In-process the bottleneck is cognitive and organizational (one class everyone edits). Across services it is additionally operational (one component everyone depends on at runtime). Recognizing that the GoF liability and the ESB critique are the same sentence at different scales is the principal-level insight.
- A team proposes routing all inter-service calls through one central orchestrator. What questions do you ask before agreeing?Which business processes actually span domains and need compensation or status visibility — versus reactions that are independent and belong as events? Who owns the orchestrator, and will every team's change queue behind that owner? What is its availability target, given it is on the critical path of every flow? How is process state persisted so instances can scale and resume? Are participant calls idempotent, since retries are certain? And can we start with one orchestrator per process rather than one platform-wide hub?
- How do you get orchestration's visibility benefit while keeping choreography's team autonomy?Split by process ownership: each cross-domain business process gets its own small orchestrator owned by the team that owns the outcome, while intra-domain reactions stay event-driven. Keep process definitions declarative so participants' business rules do not migrate into the hub, and invest in distributed tracing plus a queryable process-state store so the event-driven parts are observable too. The goal is several narrow mediators, not one universal one.
A dialog-box controller and an enterprise service bus are the same drawing at different zoom levels: a hub with spokes. Zoomed in, an overloaded hub costs you merge conflicts; zoomed out, it costs you an outage and a cross-team release queue.