CQRS (Command Query Responsibility Segregation) is an architectural pattern that separates the operations that read data from the operations that write data into distinct models. This separation allows each side to be optimized, scaled, and evolved independently, making it a powerful approach for complex or high-traffic systems.
CQRS stands for Command Query Responsibility Segregation, a pattern coined by Greg Young based on Bertrand Meyer's Command-Query Separation (CQS) principle. In CQRS, a 'Command' is any operation that changes state (create, update, delete), while a 'Query' is any operation that reads state without modifying it. These two responsibilities are handled by entirely separate models, handlers, and often separate data stores. This is a deliberate architectural choice, not just a naming convention.
Traditional CRUD architectures use a single model for both reads and writes, which creates tension when the two sides have very different performance, complexity, or scaling requirements. CQRS allows the read side to be optimized for fast querying (e.g., denormalized views, caching) while the write side enforces strict business rules and invariants. It also makes the codebase more expressive, since every operation is explicitly classified as either a state-changing command or a side-effect-free query. This clarity is especially valuable in domain-driven design (DDD) contexts.
On the write side, a client sends a Command (e.g., PlaceOrderCommand) to a Command Handler, which validates the input, applies business logic, and persists the change to a write store. On the read side, a Query (e.g., GetOrderSummaryQuery) is handled by a Query Handler that fetches data from a read store, which may be a pre-projected, denormalized representation optimized for display. The two stores are kept in sync either synchronously or, more commonly in distributed systems, asynchronously via events or message queues. This sync mechanism is often where complexity lives.
CQRS is frequently paired with Event Sourcing, but they are independent patterns — you can use one without the other. In Event Sourcing, state changes are stored as an immutable sequence of events rather than overwriting current state, making it a natural fit for the write side of CQRS. The events emitted by the write side can then be used to build and rebuild the read-side projections. Understanding this distinction prevents the common misconception that CQRS requires Event Sourcing.
The biggest gotcha is eventual consistency: because the read store is often updated asynchronously, a client may read stale data immediately after issuing a command. You must design your UI and API contracts to handle this gracefully, for example by optimistic UI updates or polling. Avoid applying CQRS to simple CRUD services where the overhead of maintaining two models outweighs the benefits — it is best suited for domains with complex business logic or highly asymmetric read/write loads. Keep commands intention-revealing (e.g., ShipOrderCommand rather than UpdateOrderStatusCommand) to maximize the expressiveness of your domain model.
© RM Full Stack & AI Engineer · All guides · Roadmaps · Open the app