What is Event Sourcing?
Event Sourcing is a design pattern where state changes are stored as a sequence of immutable events rather than updating a current-state record. Instead of overwriting data, you append facts about what happened.
The Problem with Traditional CRUD
In a typical CRUD application, you store only the current state:
# Traditional: only current state is stored
UPDATE accounts SET balance = 800 WHERE id = 1;
This tells you what the balance is, but not why it changed. Did someone deposit $800? Withdraw $200? Was it a correction? You've lost the history.
The Event Sourcing Approach
With Event Sourcing, you store events — immutable facts about what happened:
# Event Sourcing: store what happened
AccountOpened(account-id: 1, initial-balance: 1000)
AmountWithdrawn(account-id: 1, amount: 200)
AmountDeposited(account-id: 1, amount: 500)
AmountWithdrawn(account-id: 1, amount: 500)
The current balance ($800) is derived by replaying all events. The event stream is the source of truth.
Core Principles
| Principle | Description |
|---|---|
| Immutability | Events are never modified or deleted. They are facts about the past. |
| Append-only | New events are appended to the end of the stream. No updates or deletes. |
| Derivation | Current state is computed by replaying events from the beginning. |
| Temporal queries | You can reconstruct state at any point in time by replaying events up to that point. |
| Multiple views | The same event stream can feed multiple projections for different purposes. |
Benefits
Complete Audit Trail
Every state change is recorded. You always know what happened, when, and why. This is invaluable for debugging, compliance, and analytics.
Temporal Queries
Need to know what an account balance was on March 15th? Replay events up to that date. Traditional systems struggle with this; event-sourced systems do it naturally.
Flexible Read Models
Need a dashboard view? A fraud detection view? A monthly report? Each is a separate projection built from the same event stream. Add new projections without changing the write model.
Bug Recovery
Found a bug in your projection logic? Fix the code and replay all events. The correct state emerges from the immutable event history.
Event Sourcing introduces complexity. The event stream grows over time, requiring consideration of snapshots for performance. Event schema evolution needs careful handling. It's most valuable when audit trails, temporal queries, or multiple read models are genuine requirements.
How Sourcing Implements Event Sourcing
The Sourcing library provides two key constructs:
- Aggregations — The write side. Validate commands against current state and emit events.
- Projections — The read side. Consume events to build query-optimized models.
Together, they implement the CQRS pattern, separating concerns while maintaining consistency through the event stream.
Next Steps
- Learn about CQRS Pattern — how commands and queries are separated
- Explore the Architecture — how the pieces fit together
- Follow the Quick Start Guide — build your first projection