CQRS
Also known as: Command Query Responsibility Segregation
Separates read and write models for scalability and clarity.
Command Query Responsibility Segregation, articulated by Greg Young around 2010 and building on Bertrand Meyer's earlier Command-Query Separation principle (which applied at the method level — methods either return values or change state, not both), separates the data model used for commands (state-changing operations) from the data model used for queries (read-only operations) at the architectural level. The two models can have different schemas, different storage, different consistency characteristics, and different scaling profiles, with synchronization between them typically asynchronous via events. CQRS is often paired with Event Sourcing (commands produce events, events update both the write store and the read store) but the two are independent — CQRS can use a traditional database for the write side, and Event Sourcing can be used without separate read models. CQRS adds substantial complexity and is typically appropriate only when read and write workloads have substantially different requirements (e.g., complex reporting against simple writes, or vice versa).
Core components
- Write side (commands, command handlers, write model, often Aggregates from DDD)
- Read side (queries, query handlers, read model, often denormalized for query performance)
- Asynchronous synchronization (typically via events)
- Eventual consistency between sides
- Distinction from Bertrand Meyer's method-level CQS
- Optional pairing with Event Sourcing
- Distinction between simple CQRS (just separate models) and CQRS-ES (with event store)
Primary use case
Systems with substantially different read and write requirements; reporting and analytics against transactional sources; complex domain models needing separate read denormalization; integration with Event Sourcing for audit and replay; financial and regulated systems where write integrity matters and read patterns vary; foundation for some microservices patterns.
Common criticisms
- Substantial complexity overhead — CQRS without justifying complexity is anti-pattern
- eventual consistency between command and query sides is operationally difficult to reason about
- risk of stale reads immediately after writes is hard to communicate to product teams expecting strong consistency
- debugging across two models is harder than within one
- the often-cited pairing with Event Sourcing creates additional complexity
- many implementations adopt CQRS for systems that don't justify the complexity
- tooling support varies and many DIY implementations have subtle correctness issues
- better-fitted patterns (read replicas, materialized views, separate reporting databases) often suffice.
Lineage
- Siblings
- Event-Driven Architecture, Event Sourcing, Domain-Driven Design