Skip to content
Low Level Design Mastery Logo
LowLevelDesign Mastery

Event-Driven Architecture

Building systems around events, not requests

Event-Driven Architecture (EDA) is an architectural pattern where systems communicate through events - immutable records of something that happened in the past. Unlike request-response patterns where components directly call each other, event-driven systems use an event bus or message broker to decouple producers and consumers.

Traditional architectures use synchronous request-response patterns: Service A calls Service B and waits for a response. Event-driven architectures flip this: Service A publishes an event (“OrderCreated”) and continues. Service B (and potentially C, D, E) subscribe to that event and react asynchronously.

Key Characteristics:

  • Events are immutable facts - They represent something that already happened (past tense: “OrderCreated”, not “CreateOrder”)
  • Decoupled communication - Producers don’t know who consumes their events
  • Asynchronous processing - Consumers process events at their own pace
  • Reactive - Systems react to events rather than being proactively called
  • Scalable - Add consumers without modifying producers
Diagram
  1. Events are Immutable - Can’t change past
  2. Events are Facts - Something happened
  3. Decoupled - Producers don’t know consumers
  4. Asynchronous - Non-blocking
  5. Reactive - Consumers react to events

Event sourcing is a pattern where you store all changes to application state as a sequence of events, rather than storing the current state. The current state is derived by replaying all events from the beginning (or from a snapshot).

Instead of updating a record in a database (overwriting the previous state), you append a new event to an event log. To get the current state, you replay all events. To see the state at any point in time, you replay events up to that point.

Why This Matters:

Traditional databases store the current state - you can see what something is now, but not how it got there. Event sourcing stores the history - you can see every change that ever happened, when it happened, and why it happened (if events include context).

This enables powerful capabilities: audit trails (see who changed what and when), time travel (see state at any historical point), replay (rebuild state from scratch), and debugging (replay events to understand what happened).

Diagram

Problem: Lost history! Can’t see how state changed.

Diagram

Benefits:

  • Full history - Every change recorded
  • Replay - Rebuild state from events
  • Audit trail - See what happened when
  • Time travel - See state at any point

CQRS (Command Query Responsibility Segregation)

Section titled “CQRS (Command Query Responsibility Segregation)”

CQRS (Command Query Responsibility Segregation) is a pattern that separates the read and write models of your application. Instead of using the same data model for both reading and writing, you have separate models optimized for each operation.

In traditional applications, you use the same database schema for both:

  • Commands (writes) - Create, Update, Delete operations
  • Queries (reads) - Get, List, Search operations

CQRS recognizes that these operations have different requirements:

  • Commands need consistency, validation, and business logic
  • Queries need speed, denormalization, and read optimization

The Separation:

  • Write Model - Handles commands, enforces business rules, stores normalized data, optimized for consistency
  • Read Model - Handles queries, stores denormalized data, optimized for read performance

The read model is typically updated asynchronously by consuming events from the write model, ensuring eventual consistency.

Diagram

Benefits:

  • Optimize independently - Write for consistency, read for speed
  • Scale independently - More read replicas
  • Different databases - SQL for writes, NoSQL for reads
  • Performance - Read model optimized for queries

Rebuild state by replaying events.

  1. Rebuild Read Model - After crash or migration
  2. Debugging - See state at any point
  3. Testing - Replay events in test
  4. Time Travel - See past state

Problem: Replaying millions of events is slow!

Solution: Snapshots!

Diagram

Strategy:

  • Create snapshot every N events (e.g., 10,000)
  • Replay from latest snapshot
  • Much faster!

Event Sourcing

Store all changes as events. State = replay of events. Enables audit trail, time travel, replay.

CQRS

Separate read and write models. Optimize independently. Scale independently. Better performance.

Event Replay

Replay events to rebuild state. Use snapshots for performance. Enables debugging, testing, time travel.

Events are Facts

Events represent something that happened. Immutable. Past tense. Full history of changes.