What Is Event Sourcing?
Event sourcing is a data persistence pattern in which every change to application state is recorded as an immutable event in an append-only log, rather than overwriting current state in place. The event log is the system of record; current state is derived by replaying the events in order. Because events are never modified or deleted, the log provides a complete, auditable history from which state can be reconstructed as of any point in time.
Updated
What is event sourcing?
The idea predates software: double-entry bookkeeping records transactions, not balances, and a balance is always a derivation. Databases apply the same principle internally in the write-ahead log. As an application-level pattern, event sourcing was popularized in the domain-driven design community by Greg Young and documented by Martin Fowler in the mid-2000s.
The problem it addresses is that conventional CRUD persistence stores only the latest state. Updating a row destroys the previous value, the reason it changed, and the order in which changes happened. Event sourcing keeps all three: an order isn't a row with status = 'SHIPPED' but a sequence — OrderPlaced, PaymentCaptured, OrderShipped — that explains how the current state came to be.
Event sourcing is frequently paired with CQRS, which separates the write model (the event log) from read models optimized for queries. The two are distinct patterns: CQRS does not require event sourcing, and event sourcing can exist without CQRS, but the pairing is common because the event log is awkward to query directly.
How event sourcing works
Writes append events; reads derive state. A bank account might store:
1 AccountOpened { accountId: "a-17" }
2 MoneyDeposited { accountId: "a-17", amount: 500 }
3 MoneyWithdrawn { accountId: "a-17", amount: 120 }Replaying all three yields a balance of 380. To validate a new command ("withdraw 400"), the service rebuilds the account's state from its events — or from a periodic snapshot plus the events since — and rejects the command if it would violate a rule. Concurrent writers are typically handled with optimistic concurrency: an append specifies the expected version of the stream and fails if another event landed first.
Read models are built by projections: subscribers that consume the event stream and maintain query-friendly representations — a balance table, a search index, an aggregate counter. Projections can be rebuilt from scratch by replaying the log, which is one of the pattern's most valued properties.
Why event sourcing matters in real-time systems
Projections are asynchronous. A read model is always at some position in the log, and that position trails the newest event by milliseconds to minutes depending on load and consumer health. Any system that makes automated decisions against a projection is therefore acting on derived state that may not yet reflect the latest events — the standard trade-off described in discussions of stale data.
The effect compounds when multiple consumers each maintain their own projection. Two services replaying the same log independently will, at any instant, be at different positions and hold different views of the same entity. For batch analytics this rarely matters; for sub-second decisions made concurrently by several services, the divergence between projections — not the log itself — becomes the operational problem. Event sourcing guarantees a single authoritative history, but it deliberately does not guarantee that every derived view of that history is current.
FAQ
Related terms
The saga pattern coordinates a distributed transaction as a series of local transactions, each paired with a compensating action that undoes it on failure.
The outbox pattern writes events to an outbox table in the same transaction as the business change, then relays them to a broker, avoiding dual writes.
Change data capture (CDC) identifies row-level database changes and delivers them to downstream systems as ordered events. Learn how log-based CDC works.
Eventual consistency is a distributed-systems model guaranteeing all replicas converge to the same value once updates stop. How it works, and its trade-offs.
Idempotency means an operation has the same effect whether applied once or many times. Covers its math origin, HTTP methods, and API idempotency keys.
