THIS EXPLANATION
THE ROOM
CDA·87 Computing, Data & AI 6 MIN · 8 STATIONS

Event sourcing

A Socratic walk-through of event sourcing — reasoned out one step at a time, not lectured.

abcdefgh
a

The question we started with

THE QUESTION #

Why store every change that ever happened instead of just what is true now?

An account holds 40 pounds. The usual way to record that is a row with the number 40 in it, and when money moves, the number is overwritten.

Now someone asks why the balance is 40. The row cannot say. It never held anything but the current answer, and every previous answer was destroyed by the one that replaced it. Ask yourself what was actually stored there: not the account's history, but a single conclusion with its reasoning erased.

So the question is whether that erasure was a saving or a loss — and, if a loss, whether it is worth the very different system needed to avoid it.

b

Reasoning it through

REASONING #

Consider what an accountant would do. Not overwrite a balance — append entries. Deposited 100. Withdrew 70. Deposited 10. The balance is not stored at all; it is the sum, computed when someone asks.

That inverts what is fundamental. In the first design the state is the truth and changes are transient instructions for modifying it. In the second, the changes are the truth and state is a derived thing — a fold over the sequence, recoverable at any time by replaying it. That inversion is event sourcing, and almost everything else follows from it.

Follow the consequences honestly rather than listing benefits.

You can now answer "why". The sequence is the explanation, so a disputed balance is investigated by reading rather than by inference from logs written for some other purpose.

You can ask about the past. What was the balance on the first of March? Replay to that point. In the overwriting design that question is unanswerable unless someone anticipated it and built history keeping — and notice the asymmetry: an event log answers questions nobody thought of when it was designed, because it kept the inputs rather than one conclusion drawn from them.

You can also build a new conclusion from old facts. Suppose next year you want the average time between deposits. The overwriting system never recorded it and cannot recover it. The event log can, because that fact was implicitly there all along. This is the underrated benefit: the log lets you compute answers to future questions from past data.

Now the costs, which are substantial and are where projects come unstuck.

Reading becomes work. Every query on state either replays the log or reads a maintained projection — a stored view kept up to date as events arrive. In practice you always build projections, which means you now maintain derived stores and accept that they lag the log.

Events are immutable, and that collides with the world. A wrongly recorded event cannot be edited; it must be corrected by appending a compensating event, exactly as accountants post a reversing entry. This is a discipline, and applications that expect to update rows find it awkward.

Personal data collides with it harder. A regulation obliging you to erase someone's data is difficult to satisfy against an append-only store whose value depends on being append-only. The usual approach is crypto-shredding — storing personal fields encrypted and discarding the key — and it is a workaround with genuine open questions rather than a settled answer.

And the hardest cost is versioning. Your event schema changes over time, but you still hold events written under old schemas years ago, and replay must interpret all of them. There is no way to migrate the past without falsifying it. Serious event-sourced systems spend real effort on upcasting old events, and this, more than storage volume, is what makes the approach demanding.

c

The analogy

THE ANALOGY #
THE FIGURE

Think of a ship's log against a pin on a chart. The pin shows where you are; the log records every heading and every duration sailed. Anything the pin tells you, the log can reconstruct — but the log also answers where you were on Tuesday, whether you ever entered a restricted zone, and why you drifted, none of which the pin can. What the log costs is that finding your current position means adding up the whole voyage, which is why navigators keep the pin as well.

WHERE IT BREAKS DOWN

A ship's log is a passive record read by humans, whereas an event log is the only copy of the truth — the pin is regenerated from it, so a corrupted or unreadable log does not merely lose history, it loses the present too.

d

Clarifying the model

THE MODEL #

Three refinements are worth pinning down.

First, an event is a statement about the past, not a request. "MoneyDeposited" — something that happened and cannot be declined. That is why events are immutable and why naming them in the past tense is more than a style rule: a log full of imperatives is a queue of commands, which is a different thing with different guarantees.

Second, the projection is disposable and the log is not. This is the practical test of whether a system is genuinely event sourced: you should be able to delete every read store and rebuild it from the log alone. If you cannot — if some state exists only in a projection — then the log is not the source of truth and you have taken on the costs without the benefit.

Third, and most important in practice: this is not a general-purpose default. It earns its cost where history is intrinsically valuable — ledgers, orders, regulated processes, anything with an audit obligation or a genuine need to reconstruct the past. For a table of user preferences, the current value is the whole of what anyone wants, and event sourcing buys nothing while charging fully. The common failure is not choosing it wrongly for a ledger; it is applying it uniformly to an entire system in which most of the state is not path-dependent at all.

e

A picture of it

THE PICTURE #
Event sourcing
Event sourcing Each arrow is an appended event and each box a condition the account is in only as a consequence of the events so far -- nothing in the picture is written to disk except the arrows. Start at the entry marker and walk any path: where you end up is what a replay would compute, and the loop back from overdrawn shows that correction happens by appending a further event, never by editing an earlier one. {"generator":"mermaid-svg-renderer@3.2.1","source":"../Socrates/.diagram-cache/_src/event-sourcing.md","sourceIndex":1,"sourceLine":4,"sourceHash":"a284abf5d18bafa01a46c35e47fb39a50cb21f94d62b69e49a171d0d153aadc6","diagramType":"stateDiagram","layoutVariant":"source","repairedDuplicateIds":[],"motion":"entrance-with-reduced-motion-fallback","presentation":"editorial","attempt":1,"viewBox":{"x":0,"y":0,"width":939,"height":944},"qa":{"passed":true,"findings":[]}} account opened MoneyDeposited 100 MoneyDeposited 10 MoneyWithdrawn beyondbalance MoneyDeposited clears it AccountClosed debt written off Empty Funded Overdrawn Closed State is not stored.It is the fold of everyevent replayed in order.

How to readEach arrow is an appended event and each box a condition the account is in only as a consequence of the events so far — nothing in the picture is written to disk except the arrows. Start at the entry marker and walk any path: where you end up is what a replay would compute, and the loop back from overdrawn shows that correction happens by appending a further event, never by editing an earlier one.

f

What became clearer

WHAT CLEARED #
WHAT CLEARED

Storing state overwrites the reasoning that produced it; storing events keeps the reasoning and derives the state on demand. That is a genuine reversal of what counts as the truth, and it buys explanation, time travel, and answers to questions not yet asked — at the price of maintaining projections, correcting only by appending, and interpreting old event schemas forever. Which makes it the right answer where history is part of the subject, and an expensive mistake where it is not.

g

Where to go next

ONWARD #
  • Snapshots: storing a periodic fold so replay does not start from the beginning.
  • Event schema versioning and upcasting, the approach's most persistent practical burden.
  • How separating the read model from the write model complements event sourcing without requiring it.
h

Key terms

TERMS #
TermWhat it means
Eventan immutable record that something happened, named in the past tense.
Projectiona derived, queryable view built by folding events; disposable and rebuildable.
Compensating eventa later event that corrects an earlier one, since events are never edited.
Upcastingtranslating events written under an old schema into the current one at replay time.

Every term the collection defines is gathered in the glossary.

Nearby on the shelf

4