# Event sourcing and CQRS

> Store the events, derive the state — and read from models built for reading.

Concept · Async work & messaging · https://levelcode.org/concepts/event-sourcing-cqrs

Two patterns that are often used together, but are separate ideas.

## Event sourcing

Instead of storing the current state of an entity and overwriting it, store the **sequence of events** that happened to it, and derive the state by replaying them.

```text
account 7:
  AccountOpened   {owner: "ana"}
  MoneyDeposited  {amount: 100}
  MoneyWithdrawn  {amount: 30}
→ current balance = 70
```

**Benefits**

- A complete, immutable audit history — why the state is what it is, not just what it is.
- Rebuild state, or build entirely new views, by replaying events.
- Natural fit with event-driven systems: the events are already there to publish.

**Costs**

- Querying current state needs projections (below); replaying long histories needs periodic **snapshots**.
- Events are forever, so their schemas must evolve compatibly (versioning, upcasting old events).
- Correcting mistakes means writing compensating events, not editing history.
- More complexity than most CRUD domains justify.

It shines where history is the point: ledgers and accounting, order lifecycles, audit-heavy domains. The payment lesson's double-entry ledger is a close relative: append-only entries from which balances are derived.

## CQRS (command query responsibility segregation)

Use **separate models** for writes (commands) and reads (queries). The write model enforces business rules; one or more **read models** (projections) are shaped for specific queries — a denormalized table, a search index, a cache — and are updated from the write side's events.

- Reads can scale and be optimised independently.
- Read models lag the write model briefly (eventual consistency), so the UI must tolerate it — for example by showing the user's own change from the command's result.

## Using them sensibly

You can use CQRS without event sourcing (a normal database plus read models fed by an [outbox](https://levelcode.org/concepts/transactional-outbox)), which is common and useful. Event sourcing almost always implies CQRS. Apply either to the parts of a system that need it, not to everything. See [normalization vs denormalization](https://levelcode.org/concepts/normalization-vs-denormalization).
