Skip to content

The Command Query Responsibility Segregation (CQRS) pattern

Pattern · Chapter 7

  • Traditionally one object model serves both reads and writes, forcing compromises:
    • The same entity representation must cover all CRUD operations → bloated classes carrying every property for every scenario.
    • Security/authorization is harder because each class is used for both read and write.
    • In collaborative domains, parallel operations on the same data risk contention (locking) or update conflicts.
    • Read and write workloads have different performance and scalability needs.
  • Split into two models:
    • Query model → responsible for reads. Query objects only return data and do not alter state.
    • Command model → responsible for updates. Command objects alter state and do not return data.
  • Principle: asking a question should not change the answer. Mutating state requires a command.
  • Reads go through the query model, writes through the command model; a command may read only what it needs to complete.
  • Optional next level: separate databases per model, each with a schema optimized for its use. The two stores must then be kept in sync (often via events).
  • Not required, but CQRS and event-sourcing complement each other.
  • Events communicate state changes so the query model stays current as the command model updates.
  • The event store (source of truth) lets you replay past events to rebuild the query store’s denormalized data.
  • Well suited to complex domains; SoC minimizes and manages complexity → more maintainable, extensible, flexible.
  • Teams can split: one on the query model, one on the command model.
  • Performance: optimize each schema (query store can be denormalized for fast reads).
  • Scalability: scale read and write workloads independently.
  • Security: each class is read-only or write-only → easier to enforce and test, less risk of exposing data/operations.
  • Overkill for simple CRUD; adds complexity, especially with event-sourcing. Apply only to the subsystems where it pays off — not necessarily the whole system.
  • Separate read/write stores → reads may return stale data.
  • With separate databases, the system follows an eventual consistency model (some delay before read store catches up) — contrasted with a strong consistency model where changes are atomic and transactions complete only when all changes succeed (or roll back).
  • Software Architect’s Handbook (Packt, 2018), Ch.7 “The Command Query Responsibility Segregation pattern”, pp. 551-557.