What Is Event-Driven Architecture?
In a traditional system, services call each other: the order service calls payments, then inventory, then email. Each call waits for the next, and each service must know about all the others.
In an event-driven architecture (EDA), services announce what happened instead: "OrderPlaced." Anyone who cares listens and reacts. The order service doesn't know or care who's listening.
That one change, from "tell others what to do" to "announce what happened," reshapes how systems scale, fail and evolve.
🎯 Quick Answer (30-Second Read)
- An event is a fact about the past:
OrderPlaced,PaymentFailed,UserSignedUp. - Producers publish events to a broker (Kafka, RabbitMQ, SNS/SQS, EventBridge). Consumers subscribe and react independently.
- Benefits: loose coupling, easy to add new features, spikes absorbed by the broker, better resilience.
- Costs: eventual consistency, harder debugging, duplicate and out-of-order events, and multi-step processes needing sagas.
- Use it when many parts of a system react to the same things. Avoid it for simple CRUD apps.
Request-Driven vs Event-Driven
Order service calls Payment, Inventory, Email and Analytics in turn. Adding "loyalty points" means changing the order service. If Email is down, the order may fail.
Order service publishes OrderPlaced. Each service subscribes. Adding loyalty points means a new subscriber, with no change to the order service. If Email is down, its events wait.
(Kafka, EventBridge...)"]] BUS --> PAY["Payments"] BUS --> INV["Inventory"] BUS --> EM["Email"] BUS --> AN["Analytics"] BUS -.->|"added later,
no changes upstream"| LOY["Loyalty points"] PAY -->|"PaymentCaptured"| BUS INV -->|"StockReserved"| BUS
Events vs Commands
| Command | Event | |
|---|---|---|
| Tense | Future: "ReserveStock" | Past: "StockReserved" |
| Intent | Asks one specific service to do something | States a fact; anyone may react |
| Can be rejected? | Yes | No, it already happened |
| Receivers | Exactly one | Zero, one or many |
Naming events in the past tense is a simple habit that keeps the design honest.
Three Event Styles
- Event notification: a thin event, "Order 981 was placed." Consumers call back for details if they need them. Simple, but creates follow-up traffic.
- Event-carried state transfer: the event includes the data consumers need (items, amount, address). Consumers don't call back, so services stay independent even if the producer is down.
- Event sourcing: the events are the database. Instead of storing current state, you store every event, and state is rebuilt by replaying them. Great for audit trails (ledgers, banking), but adds real complexity.
Multi-Step Workflows: Sagas
Without a single database transaction across services, how do you handle "charge payment, reserve stock, book delivery," where any step can fail? A saga: a chain of local steps, each with a compensating action if a later step fails.
Two styles:
- Choreography: each service reacts to events and publishes its own. No central controller, but the overall flow can be hard to see.
- Orchestration: a coordinator tells each service what to do next. Easier to follow and monitor, at the cost of a central component.
The Hard Parts
- Idempotent consumers: processing the same event twice must be safe (Idempotency Explained)
- Ordering: if order matters, partition events by a key (e.g. order ID) so related events stay in sequence
- Schema evolution: add fields, don't rename or remove them; use a schema registry for big systems
- The outbox pattern: write the database change and the event to an "outbox" table in one transaction, then publish from it, so you never update the DB but lose the event
- Tracing: add correlation IDs to every event so you can follow one order across services
- Dead letter queues for events that keep failing
When to Use It (and When Not To)
| Good fit | Poor fit |
|---|---|
| Many services react to the same business events | A small app with a single database |
| Spiky workloads that need buffering | Operations needing an immediate, consistent answer |
| Audit trails and analytics pipelines | Teams without monitoring and tracing in place |
| Integrating with external systems (webhooks) | Simple CRUD screens |
Frequently Asked Questions
What is an example of event-driven architecture?
An e-commerce site where the order service publishes an OrderPlaced event, and separate payment, inventory, email and analytics services each react to it independently. New features, like loyalty points, can be added as new subscribers without changing the order service.
Is event-driven architecture the same as microservices?
No. Microservices describe splitting a system into independently deployable services. Event-driven architecture describes how components communicate, by publishing and reacting to events. Many microservice systems use events, but microservices can also communicate through direct API calls.
What is the difference between event sourcing and event-driven architecture?
Event-driven architecture is about services communicating through events. Event sourcing is a storage approach where you persist every event and rebuild state by replaying them. You can use event-driven communication without event sourcing, and most systems do.
Conclusion
Event-driven architecture lets services announce facts instead of calling each other, which makes systems more decoupled, extensible and resilient to spikes. The trade-off is eventual consistency and more complexity: you need idempotent consumers, careful ordering, the outbox pattern, sagas for multi-step workflows, and good tracing.
Sources
- Martin Fowler: What do you mean by "Event-Driven"?
- Chris Richardson, microservices.io: Saga pattern
- microservices.io: Transactional outbox
Last verified: 2 November 2026.
Related reads: Message Queue Explained · Microservices Architecture Explained · Idempotency Explained · Notification System Design
I write about system design and how real products are built. Follow on LinkedIn or X, or invite me to speak.