Concepts / Remembering / What is an Event Store?
Remembering

What is an Event Store?

This guide explains what an event store is, what it guarantees, and how it differs from the databases and message brokers it is often confused with. Almost every guide on Event Sourcing takes the event store for granted – this is the place where it is introduced on its own.

Event Sourcing records every change as an event. The event store is where those events are kept. It is not just a database that happens to hold events, but a system built for one job: to keep an immutable, ordered history of everything that happened, and to make that history available for as long as the system lives.

Current State Versus History#

Most databases keep the current state of things. When something changes, the new value replaces the old one. A library database might store that book 42 is borrowed – and once it is returned, that it is available again. How often the book was borrowed, by whom, and when, is gone, unless someone thought of recording it separately.

An event store keeps the history instead. For the same book, it holds book-acquired, book-borrowed, book-returned, and book-borrowed again, each as a fact of its own. The current state is not stored, it is derived by replaying the events in order – and so is every state the book was ever in. For more on how replaying works, see Introduction to Event Sourcing.

What an Event Store Guarantees#

To keep a history that can be trusted, an event store guarantees four things:

  • Append-only. Events are only ever added. Nothing is overwritten, and nothing is removed in the course of normal operation.
  • Immutability. Once written, an event stays exactly as it was written. Its data does not change later.
  • Order. The events of a stream stay in the order in which they were written, and every reader sees them in that order.
  • Durability. Once the event store has confirmed a write, the event is not lost – not after a restart, and not after a crash.

Each guarantee protects the history in its own way. Without append-only and immutability, the history could be rewritten after the fact. Without order, replaying the same events could lead to a different state. And without durability, a decision could be confirmed whose event never made it to disk. Together, they make the history a reliable source of truth.

Streams and Subjects#

An event store does not keep events as one undifferentiated pile. Events are grouped into streams, usually one per entity – one book, one reader, one loan. In the vocabulary of CloudEvents, the stream an event belongs to is identified by its subject, a path-like identifier such as /books/42.

Streams are what make a replay practical: to rebuild the state of one book, you read the events of its stream, not the entire history of the library. They are also the natural unit of consistency, which is why an aggregate usually corresponds to exactly one stream.

Corrections Are New Events#

Since events cannot be changed, mistakes are not fixed by editing them. If a late fee was charged wrongly, the event store does not lose the late-fee-charged event. Instead, a new event such as late-fee-waived records the correction. The history shows both the mistake and its correction, just as an accountant's ledger does.

This has a valuable side effect: the same events always lead to the same result. A report, a read model, or a dataset for training a model can be rebuilt from the history today and produce exactly what it produced yesterday, because nothing in the history has moved underneath it. Where personal data must be erased for legal reasons, this calls for dedicated techniques rather than edits – see GDPR Compliance.

More Than an Audit Log#

A common misunderstanding is to see the event store as an audit log: a record kept on the side, next to the real data. In an event-sourced system, it is the other way around. The event store is the real data. There is no separate current state that could disagree with it – everything else is derived from it.

That is what makes the history useful far beyond auditing. Read models can be discarded and rebuilt at any time, new views of the data can be created years later without touching the logic that writes events, and the behavior of the system can be explained with the facts that caused it.

Event Store Versus Message Broker#

Message brokers also keep events in order, so the two are easily confused. Their purpose differs, though. A broker is a means of communication: it distributes messages from producers to consumers, and its log often keeps messages only for a limited time, until every consumer has moved on.

An event store is a means of remembering. It keeps events for good, reads the events of a single stream on demand, replays a history from its beginning, and checks conditions when writing. Many systems use both: the event store as the memory of a system, and a broker to tell other systems about what happened – see Event-Driven Architecture for that second role.

What Event Sourcing Asks of an Event Store#

Storing events safely is the foundation, but an event-sourced system needs a few more things from the place that keeps them:

  • Writing with conditions. A decision is based on the state at the time it was made. The event store has to be able to reject a write if the stream has changed in the meantime, so that no decision is recorded on stale state – this is known as optimistic concurrency.
  • Reading. Rebuilding the state of an entity means reading its stream, from the beginning or from a known point.
  • Observing. Read models and reactions need to learn about new events as they happen, without constantly asking for them.
  • Querying. For debugging and analysis, it helps to search across streams, for example by event type or time.

Whether a system offers these directly or they have to be built around it makes a large difference in the effort it takes to build on it. How conditions on writes are used in practice is shown in Designing Aggregates and Dynamic Consistency Boundaries (DCBs).

Try it with EventSourcingDB

EventSourcingDB is a database built as an event store: it writes events append-only and in order, checks preconditions when writing, and lets you read, observe, and query events. To write and read your first events, follow First Steps with EventSourcingDB.