Event Sourcing stores state changes as a sequence of events. CQRS separates read and write operations. Together, they enable powerful patterns for complex systems.
What is Event Sourcing?
Traditional State Storage
Traditional approach:
┌─────────────────────────────────┐
│ Account │
│ ───────── │
│ id: acc_123 │
│ balance: $500 │
│ status: active │
└─────────────────────────────────┘
Question: How did we get to $500?
Answer: Unknown 🤷
Event Sourcing Approach
Event sourcing approach:
┌─────────────────────────────────┐
│ Events for acc_123 │
│ ───────────────── │
│ 1. AccountOpened($0) │
│ 2. MoneyDeposited($1000) │
│ 3. MoneyWithdrawn($300) │
│ 4. MoneyWithdrawn($200) │
└─────────────────────────────────┘
Current state: $1000 - $300 - $200 = $500
Full history available ✓
Implementing Event Sourcing
Event Store
Aggregate with Events
Repository
CQRS (Command Query Responsibility Segregation)
The Problem
Without CQRS:
┌─────────────────────────────────────┐
│ Same model for reads and writes │
│ ───────────────────────────────── │
│ - Write optimized for consistency │
│ - Read needs denormalized data │
│ - Conflicts in design decisions │
└─────────────────────────────────────┘
CQRS Solution
With CQRS:
┌─────────────────┐ ┌─────────────────┐
│ Write Model │ │ Read Model │
│ ───────────── │ │ ───────────── │
│ - Commands │ │ - Queries │
│ - Aggregates │ │ - Projections │
│ - Consistency │ │ - Optimized │
└────────┬────────┘ └────────▲────────┘
│ │
│ ┌─────────┐ │
└────▶│ Events │───────┘
└─────────┘
Write Side
Read Side (Projections)
Snapshots
Benefits and Trade-offs
Benefits
✓ Complete audit trail
✓ Time travel (rebuild state at any point)
✓ Event replay for debugging
✓ Separate read/write optimization
✓ Scalable read models
✓ Easy to add new projections
Trade-offs
✗ Increased complexity
✗ Eventual consistency between read/write
✗ Event schema evolution challenges
✗ More infrastructure (event store, projections)
✗ Learning curve
When to Use
Good fit:
- Audit requirements
- Complex domain with many state transitions
- Need for multiple read models
- High read/write ratio
Not ideal:
- Simple CRUD applications
- Strong consistency requirements
- Small teams without event sourcing experience
Conclusion
Event sourcing and CQRS are powerful patterns for complex domains. They provide complete audit trails, enable flexible read models, and support scalable architectures.
Start simple: event sourcing alone adds significant value. Add CQRS when you need optimized read models. The patterns work best together but aren't required to be used together.