Source · Bellemare, Building Event-Driven Microservices (O'Reilly); Newman, Building Microservices 2e (O'Reilly)
Why this matters
Newman, Building Microservices 2e, Ch. 4 (Communication Styles)Once services own their own data, you cannot wrap a change across several of them in a single database transaction. Synchronous request/response chains also make services fragile: if service A must call B which calls C to complete a request, the availability of A becomes the product of the availability of all three, and latency stacks up. Event-driven communication addresses both problems by letting services react to facts that have happened rather than commanding each other in real time.
Understanding the event-driven style is essential because it changes how you reason about consistency, coupling, and failure. It buys strong decoupling and resilience, but it demands that you embrace eventual consistency and design for asynchronous flows that are harder to trace.
The concept
Bellemare, Building Event-Driven Microservices, Ch. 1-2; Newman, Building Microservices 2e, Ch. 6 (Sagas)In event-driven architecture, services emit events - immutable statements that something happened, such as 'OrderPlaced' - onto a broker or event stream. Interested services subscribe and react. The emitter does not know or care who consumes the event, which is the source of loose coupling.
A key distinction is choreography versus orchestration. In choreography, each service reacts to events and emits its own, and the overall workflow emerges from these local reactions with no central controller. In orchestration, a central coordinator explicitly tells each service what to do next. Choreography maximizes decoupling but makes the end-to-end process harder to see; orchestration makes the process explicit at the cost of a coordinating component that all steps depend on.
Event streams (as in Kafka) go further than transient messaging: events are retained in an ordered, replayable log, so new consumers can rebuild state by reading history. Because updates propagate asynchronously, the system is eventually consistent - different services briefly hold different views until the events settle. To coordinate multi-step business operations that span services, you use a saga: a sequence of local transactions where each step publishes an event, and failures are handled by emitting compensating actions rather than by rolling back a global transaction.
Worked scenario
Newman, Building Microservices 2e, Ch. 6 (Sagas, compensating transactions)An order flow must reserve inventory, charge payment, and schedule shipping across three services. A distributed ACID transaction across three databases is impractical, so you model it as a saga.
Order Service publishes 'OrderPlaced'. Inventory reserves stock and publishes 'StockReserved'. Payment charges the card and publishes 'PaymentTaken'. Shipping schedules delivery. Now suppose payment fails after stock was reserved. There is no global rollback; instead Payment publishes 'PaymentFailed', and Inventory, subscribing to that event, runs a compensating action to release the reservation. The order ends in a consistent 'cancelled' state, reached through forward events and compensations rather than a single atomic transaction.
This is choreography: no central brain, each service reacting locally. The trade-off is visibility - to answer 'why did this order cancel?' you must trace a chain of events across services, which is why observability and correlation IDs are non-negotiable in event-driven systems.
How it connects
Bellemare, Building Event-Driven Microservices, Ch. 13 (Supportive tooling)Event-driven design is the practical answer to the consistency problem raised by data ownership in the fundamentals topic: you replace distributed transactions with sagas and eventual consistency. It deepens the loose coupling that independent deployability requires, because emitters and consumers evolve separately.
It also interacts with API design: many systems expose synchronous REST for queries but use events internally for state propagation, and event schemas need the same disciplined versioning and contract testing that public APIs do. Finally, the visibility cost of choreography is exactly what pushes teams toward strong observability, distributed tracing, and, where a process is complex, a deliberate choice to orchestrate instead.
- Confusing choreography with orchestration. Choreography has no central controller; orchestration does. Mixing them up leads to the wrong reasoning about coupling and visibility.
- Treating eventual consistency as a bug to eliminate. In an event-driven system it is the normal, intended state; you design UX and reads around it rather than forcing synchronous updates.
- Assuming a saga 'rolls back' like a database transaction. Sagas have no global rollback; failures are handled by explicit compensating actions that undo prior steps.
- Events are immutable facts; emitters publish them without knowing consumers, which produces strong decoupling.
- Choreography spreads workflow logic across reacting services (max decoupling, low visibility); orchestration centralizes it in a coordinator (explicit flow, a shared dependency).
- Multi-service operations use sagas with compensating actions and accept eventual consistency instead of distributed ACID transactions.