PatternChapter II · Styles & patterns · Building block 7 of 8

Event Sourcing

Event sourcing stores state changes as ordered events. The current state is built up by playing back this history.

  1. Event loggingOrdered List of Business Facts
  2. PlayingRecalculating state from events
  3. Append onlyDon’t overwrite anything, just add

Context

Why this is important

Who only stores the current status, loses the origin: How did the order come to this value? Event sourcing only attaches any business change as an event; the state is created by playback. The price is permanent additional expense. For mere publication of saved changes, see Transactional Outbox.

This building block declares events as the authoritative state memory. For mere publication of saved changes, see Transactional Outbox.

At a glance · Condition of event sequence

The aggregate attaches events to the event store; the current state is created by playing, projections build reading views from it.
Shop example · Playing events

Play state from events

An experimental order component stores each accepted change to B-1042 as an event. The rest of the shop remains a modular monolith.

This is how you read the picture

  1. Event logging Lines v1 to v4 in the order log
  2. Playing The controller applies the events up to the version
  3. Append only In CRUD mode, each change overwrites the row; the history is missing

Event log · Attach only · Stream order B-1042

  1. v v110:00Order Created2 × cup
  2. v v210:01Reserved stockReservation R-77
  3. v v310:02Confirmed paymentPayment received
  4. v v410:04Shipment ReleasedWarehouse may be shipped

Derived state

Status
Ready for dispatch
Order lines
2 × cup
Reservation
R-77
Payment
acknowledged

The state is played back from the events up to the selected version; any previous state remains reconstructable at any time.

Times illustrative

Move the regulator: The state arises from the events up to the selected version, the times are illustrative.

Benefits & limitations

Helps if:

  • A domain event history records changes traceably and lets you reconstruct how state evolved.
  • Ordered events make previous states derivable at a certain time.
  • Separate projections use the same history for different analyses.

Boundaries

  • Without a real need for history, replay, versioning and retention create ongoing overhead; the shop therefore uses Event Sourcing only as an experimental component.
  • Long streams slow down playback; snapshots speed up but remain derived.
  • Deletion is difficult with immutable events; plan data minimisation and Crypto Shredding before designing the schema.

In practice

  1. Define lasting stream boundaries, event meanings and ordering rules. Store business facts; evolve technical storage formats through controlled schema changes.
  2. Check the expected stream version atomically when appending. On conflict, reload the current state and reassess the change against business rules; Transaction Boundaries explains local atomicity.
  3. Version event readers and test replay against expected values. Projections remain derived read models; see CQRS for their design.
Read the detailed explanation

Event Sourcing records business state changes as ordered events. Current state is obtained by applying events in stream order. A write appends new events only if an atomic check confirms that the expected stream version still matches.

Queries often use projections derived from the history that can be rebuilt. Event versions, ordering and long-term readability become part of the data contract. Histories can make privacy and retention more demanding than mutable state records.

CQRS can project events into separate read models but is not required for an event history; Transaction Boundaries explains atomic appends with an expected version.

A snapshot stores an intermediate state from which replay continues instead of always starting at event 1. Upcasting, a Versioning technique, converts old events to a newer schema as they are read. Crypto Shredding stores personal data encrypted and deletes the key when required; this is an approach to addressing GDPR erasure requirements in an immutable event history.

Check your understanding

Test yourself in three stages

  1. ReadingCheck in the picture

    The controller is in the version 2. What status and which reservation has B-1042?

    View the solution with justification

    Status "created", reservation R-77. Payment is not yet played, so it is on “—”.

  2. ApplyingTransferred to a new situation

    The customer changes by version 4 the quantity on 3 cups. What happens in the Event Store?

    View the solution with justification

    A new event (version) 5) is attached, for example, quantity changed. The previous events remain unchanged; the state results when playing.

  3. EvaluateWeighing an alternative

    Should the whole shop switch to event sourcing because the history is useful?

    View the solution with justification

    No, not a blanket one. Advantage: comprehensible course. Disadvantage: Expenses for replay, versioning and erasability. Recommendation: Use only where the process is technically needed, as in the experimental ordering component.

Continue on the learning path

Next in Styles & patterns: Pipe & Filter.