Dictionary

Event sourcing

Event sourcing stores every change to your data as an ordered sequence of events and treats that log as the source of truth. Instead of keeping only the current state, you rebuild it by replaying the events, which gives you a full audit trail and the ability to reconstruct any past state.

What is event sourcing?

Event sourcing stores every change to your data as an event, in order, and treats that sequence of events as the single source of truth. Instead of keeping only the latest state of a record, you keep the full history of what happened to it, and you work out the current state by replaying those events from the start.

Think of an accountant's ledger. You never rub out a line. If a figure is wrong, you post a correcting entry underneath. The running total is handy, but the entries are what actually happened, and the total is only their sum.

A traditional application does the opposite. It reads a row, overwrites some fields, and the previous state is gone unless you bolted on a separate log.

How replaying events rebuilds state

Every business action appends one event to an append-only store, the event store. Append-only means you add new events and never overwrite old ones. To load an entity, the application reads its stream of events and applies them one by one, a step often called rehydration.

A bank account makes this concrete. Say the stream holds four events:

  • AccountOpened, starting balance 0.

  • Deposited, 100 euro.

  • Withdrew, 30 euro.

  • Deposited, 50 euro.

Replay them in order and the balance is 120 euro. Ask what the balance was straight after the withdrawal, and you replay only the first three events to get 70 euro. That second question, state as it stood at a chosen moment, is a temporal query, sometimes called a time travel query.

Replaying a long stream on every read is slow, so most systems store snapshots: a saved copy of the state after event N. To rehydrate, you load the latest snapshot and replay only the events after it. A snapshot is an optimisation, never the source of truth, so you can delete and rebuild it from the events at any time. For fast reads, systems also keep projections, or materialized views: query-shaped copies of the state that event handlers keep current, while the event log stays the record.

Because the raw events are kept, you can also build a projection that did not exist when the data was written. Say a manager now wants the average time between an order being placed and shipped, a number nobody thought to store. You add a new projection and replay history into it, with no change to how writes work. The same replay also rebuilds a projection that a bug corrupted. These events are a natural feed for event-driven architecture, where other services react to them as they happen.

How it differs from an audit trail and from CQRS

Event sourcing versus an audit trail

A plain audit trail sits beside your real data: the current state lives in normal tables, and a separate log records the changes for compliance. If the two disagree, the tables win and the log is only a witness. Event sourcing removes that gap, because there is no separate current-state table to disagree with. The events are the state, so the store is itself a complete audit trail rather than a report kept next to the truth.

Event sourcing versus CQRS

CQRS (Command Query Responsibility Segregation) splits the write model from the read model so each can be shaped and scaled on its own. It says nothing about how you store data. Event sourcing says the store is a log of events. The two are often used together, with an event store feeding query-friendly projections, which is why people conflate them, but you can do either one without the other.

What to watch out for with event sourcing

Old events are frozen, but their shape still changes. The event store is permanent, so you never edit a stored event. Yet a year in, your OrderPlaced event needs a new field or a renamed one, and the events already written can never be rewritten. Teams handle this with tolerant readers that ignore unknown fields, version tags on each event, and upcasters that translate old shapes to the new one on read. Plan for schema evolution on day one, not when the first migration bites.

You cannot simply delete a person. Append-only storage collides head-on with the right to erasure under the GDPR (Article 17), which lets someone ask you to delete their personal data. You cannot just DELETE their events without punching a hole in every stream that references them. The usual fixes are to keep personal data outside the event store and reference it by id so it can be deleted on its own, or to use crypto-shredding: encrypt each subject's data with a per-person key and throw the key away, which leaves the events intact but the data unreadable.

Replay must be idempotent. Consumers usually receive events at least once, so the same event can arrive twice. Handlers need idempotence so a repeat does not double-charge a card or double-count a sale. This is the same discipline you need with Change Data Capture feeds and any at-least-once queue.

An event store is not a message broker. Apache Kafka and similar brokers move events between systems well, but they are not built for reading one entity's full history or for the concurrency checks an event store needs. Use a broker to distribute events and a purpose-built event store, or a database with an append-only table, to hold the source of truth. Getting events reliably onto that broker is its own problem, usually solved with a transactional outbox.

Most systems do not need it. For plain create-read-update-delete work it is a lot of machinery for little gain, so reach for it only where the history is the point, like a payment ledger or an order pipeline where you must explain how the current state came to be.

Last Updated: July 10, 2026 Back to Dictionary
Keywords
event sourcing event log idempotence change data capture exactly-once processing apache kafka gdpr cqrs event-driven architecture audit trail data engineering