Event SourcingField notes

Event sourcing or CRUD with a history table? An honest comparison

3 min read

When traceability is required, the question comes up early: is a history table enough, or does this need event sourcing? The honest answer, in the majority of cases, is: the history table is enough. Just not in the cases where it is not — and those can be identified in advance.

What the history table gives you

The pattern is familiar: alongside the table holding the current state sits a second one, receiving a copy of every change with timestamp and user. Usually via a database trigger, so nothing is forgotten.

It is cheap, done in days, understood by every developer, and it reliably answers the most common question: what did this record look like on 3 March?

Where it breaks

It does not know the why. The history shows the discount jumping from 5% to 12%. Whether that was an approval by the sales director, a volume tier or a bug in an import is recorded nowhere. In an audit, that is precisely the question.

It only knows one table. An operation touching order, line item, reservation and credit check leaves four unconnected rows in four histories. The operation itself exists nowhere.

Deletions and restructuring eat it. A schema refactoring, a record merge, a GDPR deletion — afterwards the history has gaps, and it says nothing about them.

It is mutable. Anyone with write access to the database can change the history too. For an auditor, that is the decisive objection.

What event sourcing does differently

Instead of state, the sequence of business events is stored: order captured, discount approved, delivery reserved. Current state is derived from it. The difference is not technical but semantic — the event carries the business meaning and the trigger with it, the history table carries only the result.

The price is real and should not be talked down: a different mental model in the team, dealing with derived views and their lag, versioning events over years, a noticeable learning curve. Using event sourcing where a history table would do means paying complexity for nothing.

Side by side

History tableEvent sourcing
Time to builddaysweeks to months
Answers "what did it look like?"yesyes
Answers "why?"noyes
Operation across several entitiesnoyes
Alterable afterwardsyesno, with an append-only store
Retroactive analysis of new questionsnoyes
Learning effort in the teamlowhigh

Five questions that settle the decision

  1. Does someone outside — auditor, procurement, regulator — ask for the reason behind a change, not just the sequence?
  2. Do the interesting operations span several entities?
  3. Do analyses keep coming up that you wish you could run retroactively?
  4. Is the domain stable enough for an event model to pay off — or is the business logic still changing monthly?
  5. Is there someone in the team who will carry this after our handover?

Three yeses on 1–3 argue for event sourcing. A no on 5 argues against it, regardless of the rest.

The pragmatic middle

You do not have to decide globally. Almost every system has a small number of areas holding the decisions that count under scrutiny: approvals, prices, permissions, contract status. That is where the event history pays off. Master data, configuration and display logic stay classic. That is not a compromise, it is usually the right answer.

Further reading

Back to the blog

Articles on this topic