The Code Codex
Theme
← Notes / Architecture

note · text31 Jan 2025 · 1 min

CQRS

Command Query Responsibility Segregation: separating the model that changes data (commands) from the model that reads it (queries). The term was popularized by Greg Young, building on Bertrand Meyer’s CQS principle: a method either changes state or returns a result, never both.

command

CreateOrder

events

OrderCreated

query

ListOrders

User

Write model

rules and validation

Write database

normalized

Projection

Read database

ready for the screen

command

CreateOrder

events

OrderCreated

query

ListOrders

User

Write model

rules and validation

Write database

normalized

Projection

Read database

ready for the screen

Why separate them

Writes and reads have different needs:

  • Writes need rules, validation and consistency: a normalized, rich model.
  • Reads need to be fast and already shaped for the screen: denormalized data, sometimes in another database (Elasticsearch, Redis, a materialized view).

With separate models, each side scales and evolves on its own. Many systems have far more reads than writes.

The price
  • Eventual consistency: after a command, the read side may take a moment to reflect the change. The interface has to handle that.
  • More moving parts: two models, events and projections to maintain.

It doesn’t have to be all or nothing: you can start with the same database and just separate classes for writes and reads, and only split storage when the load demands it.

CQRS pairs well with event sourcing (storing events instead of current state), but neither requires the other.

See also: System design and Hexagonal architecture.