Command Query Responsibility Segregation (CQRS)
Command Query Responsibility Segregation (CQRS) is an architectural pattern and design principle that separates command handling (write) logic from query (read) logic.
CQRS originated in the domain-driven design community, where Greg Young first described it as a way to ease the tension between a richly modeled write side and the varied, often denormalized queries that applications tend to serve.
The split between command and read models follows a similar line drawn by Bertrand Meyer drew in command query separation, in which a command is any method that mutates state, and a query is any method that returns a value. A single model may have a mix of both commands and queries, but they are clearly distinct. CQRS lifts that method-level principle to the architectural level — to separate models.
Splitting the read and write models lets each be optimized independently. The write model enforces business invariants and accepts commands. The read model is shaped to suit queries, often as materialized views or denormalized shapes that are kept up to date asynchronously.
This pays off most when read and write access patterns differ significantly, so that optimizing them together would force compromises on one side.
A common misconception is that CQRS requires separate databases. It does not. The pattern separates the command and query models, not the storage beneath them. The two models may share a single database, use separate databases, or dispense with a database entirely. Physically isolating reads from writes, sometimes across different engines tuned for each workload, is an optional implementation detail that will suits some system designs, but it is not part of the CQRS pattern itself.
CQRS is frequently combined with event sourcing. The write model appends events to an append-only log, and the read model is built from projections over those events, kept current by change data capture or a similar synchronization mechanism. This also is not part of the CQRS pattern itself.
Trade-offs
- Independent scaling. Read and write workloads flow through separate models, so each can be scaled and provisioned on its own.
- Eventual consistency. Read views may not immediately reflect the latest writes, as is typical in distributed software. They synchronize once the projection or replication pipeline catches up.
- Added complexity. Maintaining two models, the synchronization between them, and the schemas of the read views adds design and operational cost.
CQRS is a poor fit for systems whose read and write workloads are similar and modest.