Event-Driven Architecture
Event-driven architecture (EDA) is a design pattern where system components communicate by producing and consuming events — records of something that happened — rather than making direct synchronous calls.
What It Really Means
In a traditional request-response architecture, Service A calls Service B and waits for a response. This creates tight coupling: A must know about B, B must be available, and A is blocked until B responds. Event-driven architecture inverts this relationship.
Instead of calling other services directly, a service publishes an event: "OrderPlaced," "PaymentProcessed," "UserRegistered." Interested services subscribe to these events and react independently. The Order Service does not know or care that the Notification Service, Analytics Service, and Inventory Service all consume its OrderPlaced event. It simply publishes the fact and moves on.
This decoupling is both temporal (the producer does not wait for consumers) and spatial (the producer does not know who consumes). Adding a new consumer requires zero changes to the producer. This is the fundamental scaling advantage: teams can build new features by subscribing to existing events without coordinating with the producing team.
EDA is not a wholesale replacement for synchronous communication. It is a complement. Use synchronous calls when you need an immediate response ("Is this credit card valid?"). Use events when the action can happen eventually and the producer should not be blocked ("Send a confirmation email").
How It Works in Practice
Core Components
Events: Immutable records of something that happened. An event has a type, a timestamp, and a payload. Example: {type: "OrderPlaced", timestamp: "2026-04-25T10:30:00Z", payload: {orderId: "abc-123", userId: "user-456", total: 89.99}}
Producers: Services that emit events when something significant happens. The Order Service produces events; it does not know who consumes them.
Consumers: Services that subscribe to events and react. The Notification Service subscribes to OrderPlaced and sends a confirmation email.
Event Broker: Infrastructure that transports events from producers to consumers. Apache Kafka, AWS SNS/SQS, RabbitMQ, or Google Pub/Sub. The broker handles durability, ordering, and delivery guarantees.
Real-World Example: Uber Trip Lifecycle
When a rider requests a trip, Uber's system produces a sequence of events:
TripRequested — consumed by the matching service to find a driver
DriverAssigned — consumed by the notification service to alert the rider
TripStarted — consumed by the pricing service to start the meter
LocationUpdated — consumed by the ETA service, the tracking UI, and the safety service
TripCompleted — consumed by the billing service, the rating service, and the analytics pipeline
Each consumer reacts independently. If the rating service goes down, the trip still completes and the user is still charged. The rating event is processed when the service recovers.
Event Sourcing
Event sourcing takes EDA further: instead of storing the current state of an entity, you store the sequence of events that led to that state. To get the current state, you replay the events.
A bank account using event sourcing stores: AccountOpened(balance: 0), MoneyDeposited(100), MoneyWithdrawn(30), MoneyDeposited(50). The current balance (120) is derived by replaying these events. This gives you a complete audit trail and the ability to rebuild state at any point in time.
CQRS (Command Query Responsibility Segregation)
CQRS separates the write model (commands) from the read model (queries). Writes go through the event-sourced command side. Events are projected into read-optimized views (denormalized tables, search indexes, caches). This is powerful when read and write patterns differ significantly.
Implementation