All experiments
EXPERIMENT 03 / Data architecture

CQRS.

Let writes protect the rules. Let reads serve the questions.

HOW TO READ THIS

Change one thing at a time.
The interesting part is usually why it moved.

Interactive experiment STEP 00
Switching approach resets the experiment

Write an order. Then look at what a query can actually see.

CQRS: Shared modelClient to Shared model, reads + writes. A single model serves writes and reads immediately.reads + writesCLIENTClientOrders dashboardDATABASEShared model0 orders
clientClientOrders dashboard→ Shared model · reads + writes
databaseShared model0 ordersReceives work
Baseline systemSynchronous requestDeterministic · step by step
Written orders0
Visible to reads0
Pending updates0
Read consistencyCurrent
Observation

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.

THE PROBLEM

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.

EVERY DECISION HAS A COST

What this buys, and what it charges you for.

Context, not a scorecard
Without the patternWith the patternILLUSTRATIVE / 0–100
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.
GO A LAYER DEEPER

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