Event sourcing in one paragraph
Instead of storing current state in a row, store an append-only sequence of facts (events). Current state = replay all events (or replay from snapshot).
AccountOpened { id: 1, owner: "Ada" }
MoneyDeposited { id: 1, amount: 100 }
MoneyWithdrawn { id: 1, amount: 30 }
→ balance = 70
When it wins
- Audit trail — finance, healthcare, compliance
- Temporal queries — "balance as of last Tuesday"
- Multiple read interpretations — same events → different projections
- Event-driven integration — natural publish to Kafka from event store
When to avoid
- Simple CRUD with no audit need
- Team lacks ops maturity for stream processing
- Queries need immediate consistency on write path
Default: CRUD + outbox unless domain demands audit/replay (Distributed Systems → Transactions).
Aggregates
Aggregate — consistency boundary; one stream of events per aggregate ID. Commands validate against aggregate state, emit events.
Rule: one transaction = one aggregate instance.
Snapshots
Replay 10,000 events is slow → periodic snapshot + replay events after snapshot point.
Storage options
- Event store (EventStoreDB, custom Kafka compacted topic)
- RDBMS event table + optimistic locking on version column
Distributed Systems → Messaging — log retention, partitioning by aggregate ID.
Challenges (interview favorites)
| Challenge | Mitigation |
|---|---|
| Schema evolution | Upcasters, versioned event types |
| Deletes/GDPR | crypto-shredding, tombstone events |
| Queries across aggregates | CQRS read models (next subtopic) |
| Duplicates | idempotent consumers, event ID dedup |
Cross-reference: Communication → Async Integration for event notification vs state transfer.
Further Reading
Hands-On Tasks (Optional)
Architecture drills and whiteboard exercises. Assumes Communication & Data Transfer and Distributed Systems fundamentals.
- Model bank account with events20m
Events: AccountOpened, MoneyDeposited, MoneyWithdrawn. Derive balance by replay. When add snapshots? How handle concurrent withdrawals?