Skip to content

System Design

CQRS (Split Reads From Writes)

O(1) time to apply a command to the write model · O(1) time to project a change into the read model · queries become O(1) lookups on an already-built structure, instead of recomputing summaries from scratch every time.

The idea, in plain English

Think of a restaurant kitchen and its menu board. The kitchen — the 'write side' — is built to correctly cook complicated orders, one at a time. The menu board — the 'read side' — is a simple, quick-to-scan summary customers glance at. Nobody walks into the kitchen to check what's available. Whenever the kitchen changes something, it also updates the board. CQRS splits a system the same way. CQRS stands for Command Query Responsibility Segregation — a fancy way of saying 'writing and reading are two different jobs.' Commands (do this — place an order) go through a model built for correctness. Queries (tell me this — show my order history) go through a separate, simpler model built for fast reading.

How it works

  1. 1Keep two models. The 'write model' handles commands — create, update, delete — and enforces the real rules. The 'read model' is a simplified, ready-to-read copy, shaped exactly for what queries need.
  2. 2Every time a command changes the write model, also update the read model — this step is called 'projecting' the change — so it reflects the update.
  3. 3Queries only ever read from the read model. They never touch the write model. So reads stay fast and simple, even as the write-side rules grow more complicated.

When you'd use it

Use CQRS once your app is popular enough that how you write data doesn't match how you read it. Writing is careful, one record at a time, with lots of checks. Reading needs fast summaries across many records. For example, in an order system, placing an order is complex, but showing 'orders per customer' needs to be instant. CQRS lets you optimize each side on its own, instead of forcing one model to do both jobs well.

Common beginner mistakes

  • Letting a query read straight from the write model 'just this once.' That brings back the tight link CQRS is meant to remove, and the fast read model quietly drifts out of sync.
  • Forgetting to update the read model after a command. The command succeeds on the write side, but users never see the change, because nothing projected it into what they actually read.

Try it — edit and run

Click the code to edit · press ⌘/Ctrl+↵ to run

Editable code. Tab and Shift+Tab indent. Press Escape, then Tab, to move focus out of the editor.

Expected output — hit Run to try it
Write model has 3 orders
alice: 2 orders, total $50
bob: 1 orders, total $45
carol: 0 orders, total $0
After bob orders again:
bob: 2 orders, total $60

Not sure this is the right topic? See the learning paths → or where this leads →