CQRS

Command Query Responsibility Segregation.

“Copyright © 2010 Greg Young”

Separates read and write operations for a data store into different models.

When to use

  • When read and write workloads are asymmetrical (e.g., many reads, few writes).
  • When you need to scale read and write separately.
  • When the domain logic is complex but queries are simple.

Explanation

Problem

In traditional architectures, the same data model is used to query and update a database. This works well for basic CRUD operations. However, in more complex applications, this approach can become unwieldy.

  • The write side may need complex validation and business logic.
  • The read side may need to perform many different queries, returning DTOs with different shapes.
  • Optimizing for one side may hurt the other.

Solution

CQRS separates reads and writes into different models.

  • Commands: Change the state of the system (create, update, delete). They should not return data.
  • Queries: specify what data to return. They do not change state.

Real world analogy

In a library, the “Card Catalog” (Query model) allows you to find books effectively by Author, Title, etc. The “Librarian’s Desk” (Command model) handles checking books in and out, updating records, and managing fines. You don’t update the card catalog directly when checking out a book; the process is separate.

Pros and Cons

Pros Cons
  • Separation of Concerns.
  • Independent scaling.
  • Optimized data schemas (e.g. strict normalization for writes, denormalized views for reads).
  • Increased complexity.
  • Potential for eventual consistency (if read/write stores are physically separate).
  • Comparison

    • Related Patterns: Event Sourcing (often used with CQRS), Mediator, Task Based UI.

    Code example

    Typescript

    Php