diagram.mmd — flowchart
Event Sourcing Pattern flowchart diagram

Event sourcing is a persistence pattern in which the state of an application entity is derived entirely from a chronologically ordered, immutable sequence of events rather than from a single mutable record in a database.

In a conventional CRUD system, updating a bank account balance means executing UPDATE accounts SET balance = balance - 100. The previous balance is gone. Event sourcing instead records MoneyWithdrawn { amount: 100, timestamp: ... } as an immutable fact in an event store. The current balance is derived on demand by replaying all events for that account from the beginning: deposits added, withdrawals subtracted.

This approach unlocks capabilities that CRUD systems cannot offer. The complete audit trail is built in — you can answer "what was the balance at 3pm last Tuesday?" by replaying events up to that timestamp. Bugs in business logic can be corrected by fixing the projection and replaying historical events to rebuild the read model. New features that need historical data can be added after the fact, because the raw events still exist.

The event store is append-only: events are never updated or deleted. Write operations go through a command handler that validates business rules (the current aggregate state, reconstituted from events, is checked), then appends new events. Projections subscribe to the event stream and build read models — denormalized query-optimized views — for the application's UI and API layers. Multiple projections can consume the same event stream to serve different read patterns.

Event sourcing is often paired with CQRS (Command Query Responsibility Segregation), where write and read paths are fully separated. It also integrates naturally with Event Streaming Architecture when Kafka serves as the event store, and with Saga Pattern for multi-aggregate workflows.

Free online editor
Edit this diagram in Graphlet
Fork, modify, and export to SVG or PNG. No sign-up required.
Open in Graphlet →

Frequently asked questions

Event sourcing is a persistence pattern where the state of an entity is derived from a chronologically ordered, immutable sequence of events rather than a single mutable database record. Instead of storing the current balance of an account, you store every deposit and withdrawal event and compute the balance by replaying them.
Write operations go through a command handler that reconstitutes the current aggregate state by replaying its events, validates business rules, then appends new events to the event store. Read operations are served by projections — background processes that subscribe to the event stream and build query-optimised read models. Multiple projections can consume the same events to serve different read patterns.
Event sourcing is well suited to domains with strong auditing requirements, complex business logic that benefits from temporal queries, or where bugs in projections need to be corrected by replaying historical events. Financial services, order management, and inventory systems are common fits. It is worth the added complexity when the audit trail and replayability are first-class requirements.
A frequent mistake is storing events that are too fine-grained or too coarse-grained. Over time, replaying thousands of micro-events to reconstitute state becomes slow — snapshotting the aggregate at intervals is the solution. Another mistake is mutating or deleting events, which defeats the immutability guarantee. Teams also underestimate the operational complexity of projection versioning when event schemas evolve.
Event sourcing is a persistence strategy: state is stored as a sequence of events. CQRS (Command Query Responsibility Segregation) is an architectural pattern that separates the write model from the read model. The two are complementary but independent — you can apply CQRS without event sourcing (using separate databases for reads and writes), and you can use event sourcing without a strict CQRS boundary. In practice, they are frequently combined because event sourcing's projections naturally produce the read models that CQRS requires.
mermaid
flowchart LR CMD[Command\nWithdrawMoney] --> CH[Command Handler] CH -->|load current state| ES[(Event Store\nAppend-Only Log)] ES -->|replay events| AGG[Aggregate\nReconstituted State] AGG -->|validate business rules| CH CH -->|append new event| ES ES -->|MoneyWithdrawn| P1[Projection:\nAccount Balance View] ES -->|MoneyWithdrawn| P2[Projection:\nTransaction History View] ES -->|MoneyWithdrawn| P3[Projection:\nFraud Detection View] P1 --> RM1[(Read Model:\nBalances DB)] P2 --> RM2[(Read Model:\nTransactions DB)] P3 --> RM3[(Read Model:\nFraud Signals DB)] RM1 --> Q1[Query:\nGet Balance] RM2 --> Q2[Query:\nGet History] RM3 --> AL[Alert:\nSuspicious Activity]
Copied to clipboard