Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Event Sourcing Primer

Event sourcing stores state as a sequence of events rather than as a single mutable record. Instead of updating a row in a database, you append an event describing what happened. Current state is derived by replaying events from the beginning.

Traditional State vs Event Log

Traditional (Mutable State)Event SourcedUPDATE balance = 150Current: 150UPDATE balance = 50Current: 50FundsDeposited(100)FundsDeposited(50)FundsWithdrawn(100)Replay: 100 + 50 - 100 = 50  



With traditional storage, you only know the current balance. With event sourcing, you know how you got there.

The Core Principle

Events are the source of truth.

An event represents something that happened in the past. It is immutable—you never modify or delete events. To “undo” something, you append a compensating event.

PropertyDescription
ImmutableEvents cannot be changed after creation
Past tenseNamed as facts: OrderPlaced, FundsDeposited
CompleteContains all data needed to understand what happened
OrderedSequence matters for correct state reconstruction

Reconstructing State

When you need the current state of an entity:

Event StoreAggregate  Load events for ID "ACC-001"apply(event) [For each event]Start with default stateCurrent state ready




This “replay” process runs every time you load an aggregate. For long-lived entities, snapshots optimize this by checkpointing state periodically.

Benefits

  • Audit trail — Every change is recorded with full context
  • Debugging — Replay events to reproduce bugs exactly
  • Temporal queries — Answer “what was the state at time T?”
  • Event-driven architecture — Events naturally feed other systems

Trade-offs

  • Complexity — More concepts to understand than CRUD
  • Storage growth — Event logs grow indefinitely (though events compress well)
  • Eventual consistency — Read models may lag behind writes
  • Schema evolution — Old events must remain readable forever

Next

CQRS Overview — Separating reads from writes