Question presented to candidate:
"Explain event sourcing and CQRS. Are they the same thing? How does an event-sourced service load its current state, how do two concurrent commands avoid corrupting it, how are queries served, and when would you advise a team not to use either?"
What a strong answer should cover:
Event sourcing: the source of truth is an append-only sequence of domain events per entity (a stream); current state is a fold (replay) of those events; nothing is updated in place
Optimistic concurrency on append: a command loads the stream at version N and appends with "expected version N"; a concurrent writer gets a conflict and retries
CQRS: separate the write model (commands, invariants) from one or more read models (projections) shaped for queries; they can use different stores
Projections are updated asynchronously from the event log, so reads are eventually consistent; projections can be rebuilt or added later by replaying history
Practicalities: snapshots to bound replay time, event versioning / upcasting, publishing events reliably, GDPR-style deletion in an immutable log
They are independent: CQRS works without event sourcing, and both add real complexity β use them for audit-heavy, collaborative or temporal domains, not for plain CRUD
Code / implementation expected: Optional β an event store with expected-version appends and a projection; the example shows a write conflict, projection lag, time travel and snapshots.
event-sourcing
cqrs
2
Try it yourself
Sketch your approach before you read the solution. That is what the interview tests.
Stuck? Get a hint.
A short nudge toward the approach. It will not give the answer away.
3
Solution
Target Audience: Back-end developers who have built CRUD services and keep hearing these two terms together. No prior knowledge of either assumed.
Difficulty: Hard
Verified with: Node 22.22 and Python 3.12 (both print identical output).
How to read this doc: Every idea is explained in plain language first, then tagged with π Interview term: so you also learn the exact words an interviewer expects. All behaviour shown comes from running the example; the Verified section quotes the full output.
1. Why This Even Matters β A Story First
Your bank does not store "your balance is 530" and overwrite it each time. It stores the statement: opened, deposited 100, withdrew 70, deposited 500. The balance is just the sum of the lines. Because of that, the bank can answer questions nobody planned for β "what was the balance on 3 March?", "show every deposit over 100 this
The solution is hidden so you can try first
9 min read Β· 11 sections
4
Read the code
Event store with optimistic concurrency, a lagging CQRS projection, time travel and snapshots