advanced~2.5h

Event Sourcing

Most systems store the current state and throw away how it got there. This module is what changes when you store the HISTORY instead, and derive current state from it.

Learning objectives

  • Beginner: Explain the difference between storing current state and storing a sequence of events.
  • Intermediate: Derive an entity's current state by replaying a sequence of events.
  • Advanced: Explain what a snapshot is and why event-sourced systems need one as event history grows.

◆ The problem

A typical orders table stores the CURRENT state of an order — status: SHIPPED. It has no idea the order was PENDING, then PAID, then PACKED, then SHIPPED, and exactly when each transition happened — that history is simply gone, overwritten by each successive UPDATE.

Event Sourcing stores every state-changing event as an immutable, append-only record — OrderCreated, PaymentReceived, OrderPacked, OrderShipped — and the CURRENT state is derived by replaying all of them in order, rather than being the one thing that's actually stored.

public class Order { private OrderStatus status; public static Order replay(List<Event> events) { Order order = new Order(); for (Event event : events) { order.apply(event); // each event mutates state one step at a time } return order; } private void apply(Event event) { if (event instanceof OrderCreated e) this.status = PENDING; else if (event instanceof PaymentReceived e) this.status = PAID; // ... one branch per event type } }

The current state was never stored directly at all — it's always a FUNCTION of the full event history, recomputed by replaying it.

💻 Code example

public class Order { private OrderStatus status; public static Order replay(List<Event> events) { Order order = new Order(); for (Event event : events) { order.apply(event); } return order; } }
BenefitWhy event sourcing provides it
Full audit trail, for freeEvery state change is already a permanent, timestamped record — no separate audit log needed.
Time travelReplaying only the FIRST N events reconstructs exactly what state looked like at any past point.
New read models laterA brand new denormalized view can be built by replaying ALL historical events, even ones from before that view was ever conceived.

That last row is what makes Event Sourcing pair so naturally with CQRS — new read-side projections can be built from history that already exists, not just from data going forward.

▲ Pitfall

Replaying 50,000 events to reconstruct one long-lived entity's current state, on every single read, is a real performance problem that grows worse over time as more events accumulate — event-sourced systems periodically save a SNAPSHOT (the fully-computed state at some point) so a later read only needs to replay events AFTER that snapshot, not from the very beginning of time.

✓ Quick recap

  • Event Sourcing stores the sequence of events that happened, not just the current state — current state is derived by replaying them.
  • Replaying events one at a time, in order, reconstructs state at any point in history, not just the present.
  • This gives a free audit trail and lets entirely new read models be built later from history that already exists.
  • Snapshots exist because replaying an ever-growing full event history on every read eventually becomes a real performance problem.

Want a visual for this concept?

Generate a diagram tailored to “Event Sourcing” — the AI picks whichever visual (flowchart, comparison, sequence, etc.) best fits.

Sign in to generate a visual →

Practice quiz

Next Step

Continue to Idempotency in Distributed Systems← Back to all Spring Cloud chapters