What is CQRS?

SOLID & Design Patterns Architecture Advanced 3–5 Yrs5+ Yrs Architecture 1 min read

Quick Answer

CQRS (Command Query Responsibility Segregation) splits the model that changes data (commands) from the model that reads data (queries). At its simplest that's just separate command and query classes/handlers in one database. At its most involved it's separate read and write databases kept in sync with events.

CQRS separates the write side from the read side. The reasoning is that writes and reads want different things — writes care about validation and consistency, reads care about the exact shape and speed of the data — so a single CRUD model compromises both. The version I use most is lightweight: distinct command and query objects with their own handlers, dispatched through something like MediatR, all against one database. Full CQRS with separate read and write stores synced by events is powerful but brings eventual consistency and a lot of operational cost, so I'd only reach for it when the read and write models have really diverged or read scale demands it.

The insight: reads and writes have different needs. Writes care about invariants, validation and transactions; reads care about shape, denormalisation and speed. Forcing both through one CRUD model compromises both.

  • Lightweight CQRS — CreateOrderCommand + CreateOrderHandler, GetOrderSummaryQuery + handler, often dispatched by a mediator (MediatR). One database. This is common and low-risk.
  • Full CQRS — a normalised write store and one or more denormalised read stores updated via domain events. Adds eventual consistency and operational complexity.

Use it when a bounded context has genuinely divergent read and write models, complex reporting, or high read scale. Don't apply it to a simple CRUD app — it's pure overhead there.