Event-Driven Architecture
Build systems around facts that happened, not commands you issue.
By the end of this lesson, design services that communicate through events and understand the coupling trade-off.
In event-driven architecture, services publish events — immutable statements that something happened (OrderPlaced, PaymentCaptured) — and other services react. Instead of a service commanding others ('reserve inventory'), it announces a fact and interested services respond on their own. This inverts dependencies: the producer doesn't know who consumes.
First, see the whole system. Then we’ll open it up.
Publish facts, react independently
- The order service publishes OrderPlaced to an event bus; inventory, payment, and notification services each react independently.
flowchart LR order[Order service] -->|OrderPlaced| bus[(Event bus)] bus --> inv[Inventory service] bus --> pay[Payment service] bus --> notify[Notification service]
Flavors range from event notification (thin events, consumers fetch details), through event-carried state transfer (fat events carry the data consumers need), to event sourcing (the event log *is* the source of truth; current state is a fold over events). Events pair with the outbox for reliable publishing and with sagas for cross-service workflows.
Event-driven design buys loose coupling, independent scaling, and auditability, at the cost of eventual consistency, harder end-to-end tracing (the flow is emergent), and the operational weight of a broker. Synchronous request/response is easier to follow but tightly couples caller to callee.
This is where the abstraction starts leaking.
There is no global 'now' in an event-driven system. Consumers see facts at different times and in partition-local order. Any logic that assumes all services share the same up-to-the-millisecond view of the world will produce subtle inconsistencies.
How does publishing an event differ from calling a command?
An event states a fact that happened and the producer doesn't know or care who reacts; a command tells a specific service to do something, coupling caller to callee.