Event Sourcing vs CQRS
Event Sourcing and CQRS (Command Query Responsibility Segregation) are two distinct architectural patterns that are frequently mentioned together. While they are often used in tandem to solve complex distributed system problems, they are not the same thing, nor do they strictly require each other.
1. The Relationship
- CQRS is about separating the Read model from the Write model.
- Event Sourcing is about how you store the state of your application (as a sequence of events).
You can have CQRS without Event Sourcing, and (theoretically) Event Sourcing without CQRS, but they have a symbiotic relationship.
2. CQRS without Event Sourcing
This is a very common pattern.
- Write Side: Uses a normalized relational database (3NF) optimized for data integrity and updates.
- Read Side: Uses a denormalized NoSQL database (e.g., Elasticsearch, Redis) or a separate SQL view optimized for fast queries.
- Sync: A background process or domain events sync the data from Write DB to Read DB.
- Storage: The Write DB stores the current state (e.g.,
Balance: 100), not the history.
3. Event Sourcing without CQRS
This is rare and often inefficient.
- Storage: You store state as a log of events (
Deposited,Withdrawn). - Querying: To answer "What is the balance of Account X?", you load all events for Account X and replay them. This is fine for a single entity lookup by ID.
- The Problem: How do you answer "Give me all accounts with a balance > $1000"? You would have to load every event for every account and replay them all. This is impossibly slow.
4. Why they are best friends
Event Sourcing introduces a massive problem: Querying is hard. CQRS solves this problem: Create a dedicated Read Model.
When combined:
- Write Side (Event Store): Appends
MoneyDepositedevent. Fast, simple, audit trail. - Projection (The Glue): An event handler listens to
MoneyDeposited. - Read Side (View DB): The handler updates a
UserBalancetable in a SQL/NoSQL database (UPDATE Accounts SET Balance = Balance + 100). - Query: The client queries the Read Side directly.
5. Summary Table
| Feature | CQRS Only | Event Sourcing Only | Combined |
|---|---|---|---|
| Source of Truth | Current State DB | Event Log | Event Log |
| Complex Queries | Fast (Read DB) | Very Slow (Replay) | Fast (Read DB) |
| Audit Trail | No (unless added manually) | Native (100%) | Native |
| Complexity | Medium | Medium | High |
6. Projections
In the context of Event Sourcing and CQRS, a Projection is the mechanism that bridges the gap between the Event Log (Write Side) and the Read Model.
- Definition: A projection is a function that listens to the stream of domain events and updates a specific read database or view.
- Disposable: Since the Event Log is the source of truth, projections can be deleted and rebuilt from scratch by replaying the events. This is powerful for changing requirements (e.g., "We need a new report format").
- Multiple Views: You can have multiple projections for the same data.
- Events:
OrderPlaced,OrderShipped. - Projection A (User History): Shows a list of past orders for the user.
- Projection B (Warehouse Dashboard): Shows items pending shipment.
- Events:
programming/cqrs programming/event-sourcing programming/microservices-architecture