CQRS.
Let writes protect the rules. Let reads serve the questions.
Change one thing at a time.
The interesting part is usually why it moved.
Write an order. Then look at what a query can actually see.
A single model serves writes and reads immediately.
This is CQRS with an asynchronous projection. Separate read and write models can also share a database.
One model struggles to express rich write rules and serve very different query workloads.
This experiment adds an asynchronous read projection. CQRS itself only requires separate read and write models; separate databases and event sourcing are optional.
What this buys, and what it charges you for.
ScalabilityHigher is preferable↑ 39
Read capacity can grow separately from the write model in this deployment.
LatencyLower is preferable↓ 34
A query-shaped view needs less work per read.
ConsistencyHigher is preferable↓ 47
The asynchronous read model can temporarily show an older committed value.
Implementation complexityLower is preferable↑ 43
Projection handlers and rebuild logic become part of the application.
Illustrative scores for this scenario, on a 0–100 scale. They express a direction of change, not a benchmark. Your constraints can change the result. Select a quality to explore the reasoning.
+ What improves
- Shape a read model around actual queries.
- Scale read capacity independently when stores are separated.
± What gets harder
- A separate projection may lag behind committed writes.
- More models and synchronization paths need maintenance.
Where the edges are.
A pattern is only useful once you know where it stops working. These are the boundaries worth knowing before you commit to it.
When it earns its place
- Read and write workloads have materially different needs.
When to leave it out
- Simple CRUD already meets the requirements.
- The team is not ready to reason about two models at once. Applied to a domain that did not need it, the extra machinery is a permanent drag rather than a one-off cost.
New ways to fail
- A stopped projector serves stale data.
- Duplicate or out-of-order events corrupt a naive projection.
Operating the pattern
- Measure projection lag and make rebuilds repeatable.
- Decide what the interface shows while a write has committed but its projection has not. That gap is a product surface, not only an implementation detail.
The people behind the system
- Product teams must explain pending writes and stale reads.
Other directions to consider
- One model with indexes
- Database read replicas
- Materialized views