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.
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.
- To dig deeper: CQRS, by Martin Fowler