Event Sourcing
Event Sourcing stores every state change as an immutable event. The current state is derived by replaying events, providing a complete audit trail and.
Quick answer: Event Sourcing
Event Sourcing is covered here as a practical system design concept. Event Sourcing stores every state change as an immutable event. The current state is derived by replaying events, providing a complete audit trail and. Use it to understand the Architecture Patterns idea, where it appears in production systems, and how to discuss it clearly in interviews.
Focus on the problem being solved, the main design choice, the failure mode, and the tradeoff you would defend in front of a senior engineer. This page is part of the DosiBridge system design knowledge graph, so it links related concepts, interview problems, tradeoffs, and references instead of leaving the topic isolated.
Event Sourcing stores state as a sequence of immutable events rather than overwriting current state. Instead of updating an account balance to $150, you store "deposited $50" and "deposited $100." The current state is computed by replaying all events. This gives you a complete audit trail, the ability to reconstruct state at any point in time, and the ability to derive new read models from the same event stream. Banking, trading, and healthcare systems use event sourcing for its auditability and temporal query capabilities.
| Aspect | Details |
|---|---|
| What it is | A storage pattern where all changes to application state are stored as an immutable sequence of events |
| When to use | Systems requiring audit trails, temporal queries, undo/redo, or complex event-driven projections — finance, healthcare, legal |
| When NOT to use | Simple CRUD apps without audit requirements, or systems where storage cost of every event is prohibitive |
| Real-world example | Event Store (the database) powers financial systems where regulators require a complete, immutable record of every state change |
| Interview tip | Connect event sourcing to CQRS — events are stored for writes, and projections built from events serve reads |
| Common mistake | Treating the event store as a message queue — events are persisted facts, not transient messages. They are replayed, not consumed and deleted |
| Key tradeoff | Complete audit trail and temporal queries vs storage growth, read complexity, and schema evolution challenges |
Why This Matters
Traditional CRUD stores only the current state — yesterday's data is gone unless you built a separate audit log. Event sourcing captures every change as an immutable event, making the complete history the source of truth. This is essential for financial systems (regulators demand full transaction history), collaborative editing (like Google Docs), and debugging production issues (replay events to reproduce the exact state that caused a bug). Event sourcing also enables time-travel queries: what was the account balance at 3 PM last Tuesday?
The Building Blocks
- Event Store: An append-only database of events. Each event has a type (OrderPlaced), payload (order details), timestamp, and sequence number. Events are never updated or deleted.
- Aggregate: A domain entity that processes commands and emits events. The order aggregate receives a PlaceOrder command, validates it, and emits an OrderPlaced event. State is rebuilt by replaying events.
- Snapshots: Periodic snapshots of aggregate state avoid replaying thousands of events on every load. Load the latest snapshot, then replay only events after it.
- Projections: Read models built by processing the event stream. The same events can power multiple projections: an order history view, a revenue dashboard, and an inventory tracker.
- Event Schema Evolution: Events are immutable, but their format evolves. Use upcasting (transforming old events to new format on read) or versioned event types to handle schema changes.
Under the Hood
When a command arrives (e.g., PlaceOrder), the system loads the aggregate by replaying its events from the store. If 500 events exist, it starts from the latest snapshot and replays only subsequent events. The aggregate validates the command against its current state and, if valid, emits new events (OrderPlaced, InventoryReserved). These events are appended to the event store in a single atomic operation.
The event store is append-only — think of it as a log. Events are identified by (aggregate_id, sequence_number). Optimistic concurrency ensures that if two commands target the same aggregate simultaneously, the second one fails (expected sequence number mismatch) and must retry.
Projections run asynchronously: a projector reads the event stream, builds a denormalized view, and tracks its position (the last event it processed). If a projector crashes, it resumes from its last position. If a new projection is needed (e.g., a new analytics dashboard), create a new projector that replays the entire event stream from the beginning to build its initial state. This is the true power of event sourcing — the event stream is the single source of truth, and any number of views can be derived from it.
How Companies Actually Do This
Event Store (Greg Young) A purpose-built database for event sourcing that stores events in streams, provides subscriptions for projections, and supports category-based queries natively.
Goldman Sachs uses event sourcing for trade processing. Every trade modification is an event, giving regulators a complete, immutable audit trail and enabling same-day trade reconciliation.
Shopify uses event sourcing for their order management system. Every order state change (placed, paid, shipped, returned) is an event, enabling flexible projections for merchants, analytics, and fulfillment.
Common Pitfalls
- Storing mutable state alongside events — if you update a database row AND emit an event, they can get out of sync. The event store should be the sole source of truth
- Not implementing snapshots for long-lived aggregates — an aggregate with 10,000 events takes seconds to rebuild on every command if there is no snapshot
- Deleting or modifying events to fix bugs — events are immutable facts. Instead, emit a corrective event (e.g., OrderCorrected) that adjusts the state forward
Interview Questions Worth Practicing
- How would you implement event sourcing for a banking system with millions of transactions?
- What are the tradeoffs between event sourcing and traditional CRUD for a given use case?
- How do you handle event schema evolution when events are immutable?
The Tradeoffs
- Auditability vs Storage Cost: Every change is preserved forever, which is ideal for compliance but means storage grows linearly with every mutation. Archival and compaction strategies help.
- Temporal Queries vs Read Complexity: You can query state at any point in time by replaying events up to that timestamp, but simple 'current state' queries require projections or full replay.
- Flexibility vs Schema Evolution: New projections can be built from existing events, but evolving event schemas without breaking existing projections requires careful versioning and upcasting.
How to Explain This in an Interview
Here is how I would explain Event Sourcing in a system design interview:
Event sourcing stores every state change as an immutable event rather than overwriting current state. For a bank account, instead of storing 'balance: $150', I store 'deposited $50' and 'deposited $100' — the balance is computed by replaying events. This gives three advantages: a complete audit trail (every change is recorded), temporal queries (what was the balance last Tuesday?), and the ability to build new read models by replaying the event stream. I would combine it with CQRS — events are the write model, projections are the read model. The tradeoffs are storage growth (every event is kept forever) and read complexity (you need projections for efficient queries). Snapshots mitigate the replay cost for long-lived aggregates.
Related Topics
Original DosiBridge notes for Event Sourcing
This section is written specifically for this page, not copied from a general system-design checklist. The useful way to study Event Sourcing is to connect the concept to an asynchronous workflow where replay, ordering, and poison messages shape the architecture. That framing changes the design discussion from definitions to operating choices.
What makes this topic distinct
- Ownership Boundary: For Event Sourcing, decide the ownership boundary before choosing tools; otherwise the design looks clean but fails when event changes.
- Blast Radius: For Event Sourcing, decide the blast radius before choosing tools; otherwise the design looks clean but fails when sourcing changes.
- Deployment Path: For Event Sourcing, decide the deployment path before choosing tools; otherwise the design looks clean but fails when event changes.
- Runtime Coupling: For Event Sourcing, decide the runtime coupling before choosing tools; otherwise the design looks clean but fails when sourcing changes.
- Operational Handoff: For Event Sourcing, decide the operational handoff before choosing tools; otherwise the design looks clean but fails when event changes.
Production review question
If a team adopts Event Sourcing, what observable signal proves it helped instead of only making the architecture diagram more fashionable?
Practical metric to track
Track event-sourcing health as a named dashboard or review item: combine one user-facing metric, one saturation metric, and one correctness metric. For Event Sourcing, this keeps the discussion grounded in behavior that can be measured after deployment instead of generic advice that sounds good in an interview but never gets verified.