Facilitating the Spread of Knowledge and Innovation in Professional Software Development

Write for InfoQ


Choose your language

InfoQ Homepage News Advantages of CQRS

Advantages of CQRS

This item in japanese

Today’s applications are commonly unnecessarily complex or slow because of not using Command Query Responsibility Segregation (CQRS), Gabriel Schenker claims while stating he believes CQRS to be one of the most useful architectural patterns when used in the context of complex Line of Business (LOB) applications.

Schenker thinks one reason for this complexity is that applications often contains an anaemic domain model consisting of entities with only data and separate services handling the logic, then using the same interface both for reading and changing and data. For Schenker this lack of separation is a real problem, seeing querying data as a fundamentally different concern. His reasons for keeping reads and writes apart include:

  • Often reading data is much more frequent than writing.
  • Reading data we typically retrieve a larger amount of data or lists of data compared to writing that should affect one aggregate only.
  • Reads from a user perspective has to be more performant than writes. User tends to find it easier to accept a slower response when data is changed.

To describe the basic principles of CQRS Schenker has implemented a small but real world example of a shopping site including a product catalog and a shopping cart.

Vladimir Khorikov defines three types of CQRS, and one with no CQRS for comparison:

  • No CQRS with the same domain model used both for commands and queries. This brings no code or complexity overhead but optimization for reads is hard or impossible.
  • Separated class structure using domain classes for commands and DTOs for returning read data, which will introduce some duplication. This is a level of CQRS that Khorikov believes is sufficient for most enterprise applications with a good balance between complexity and performance.
  • Separated model with different APIs and models for reads and write respectively. In addition to optimized queries this also enables caching, making it interesting for high load on reads.
  • Separated storage optimized for queries enabling even more scaling of reads and separate types of storage for writing and querying, e.g. a relational database and a NoSQL type. Synchronization of read storage commonly runs in the background causing eventual consistency on the read side. Together with the best scalability this pattern also brings the highest complexity.

Khorikov emphasizes that CQRS is not a binary choice; the level of separation should be chosen from the needs of the application with a balance between the degree of separation and the complexity introduced and it should only be brought in to meet a read scalability requirement.

Rate this Article