Command Query Responsibility Segregation (CQRS)
CQRS separates the command (write) model from the query (read) model so each is optimized and scaled independently. It excels in complex, read-diverse domains but adds eventual-consistency complexity.
Command Query Responsibility Segregation (CQRS) splits an application into two models: one that mutates state (commands) and one that reads state (queries). Instead of a single model serving both, each side is shaped for its purpose. The write side enforces business rules; the read side is denormalized for fast, query-specific access. It generalizes the older Command-Query Separation principle from method design to whole subsystems.
How It Works
Commands express intent ("place order") and are validated against the write model, which may be a normalized relational schema or an event-sourced aggregate. After a write, the change is propagated to one or more read models — materialized views, denormalized tables, search indexes, or caches — each tailored to a specific query. Queries hit these read stores directly and never touch the write model.
Propagation is often asynchronous via events, which makes the read side eventually consistent. CQRS does not require event sourcing, separate databases, or async messaging, though it is frequently combined with them. The minimal form is simply distinct read and write models in the same database.
When to Use It
Apply CQRS when read and write workloads diverge sharply: a domain with complex write-side invariants but many varied, high-volume read shapes; systems that must scale reads independently of writes; or collaborative domains with task-based UIs. It is especially powerful when paired with event sourcing for auditability.
Trade-offs
CQRS adds significant complexity: two models to keep in sync, eventual consistency to reason about, and more moving parts to operate. It is over-engineering for simple CRUD applications, where a single model is clearer and cheaper. Read models can lag writes, so the UI must handle stale reads gracefully. Rebuilding read models and handling duplicate or out-of-order events demands discipline. Adopt CQRS selectively, per bounded context, not system-wide by default.
Related Patterns
CQRS pairs naturally with event-sourcing (the write log) and materialized-view (the read stores), and propagation typically rides an event-driven-architecture.
Example
An order-management service writes commands to an event-sourced aggregate. Each event updates several read models: a denormalized orders table for the customer's history, an Elasticsearch index for support search, and a metrics roll-up for operations. Reads are fast and purpose-built, while the write model guarantees that order invariants hold.