Facilitating the Spread of Knowledge and Innovation in Professional Software Development

Write for InfoQ


Choose your language

InfoQ Homepage News A Critical Look at CQRS

A Critical Look at CQRS

This item in japanese

Looking at Command Query Responsibility Segregation (CQRS) in a larger architectural context there are other architectural styles available, e.g. Event-Driven Architecture (EDA) and Publish-Subscribe. There are also traditional database technologies available that may solve the same problems but in a much simpler way, Udi Dahan states looking into different ways of approaching CQRS. When CQRS is really needed he claims there is an alternative way of implementing that fulfils a lot of the CQRS goals but with fewer moving parts compared to traditional CQRS.

Scalability is one reason for a CQRS approach that Dahan, one of the forefront figures of CQRS together with Greg Young, repeatedly finds when talking to customers. With a large amount of reads, separating reads from writes enables scaling of the queries, but Dahan notes there is already technology available that does read/write separation with little or no code written which he thinks developers should be aware of. One other reason Dahan thinks exists is a social pressure of adopting CQRS since so many talks about it worldwide.

One alternative for achieving scalability in a read intensive environment is master/slave replication with one master where data is modified and one or more read slaves to which all changes are replicated. This is an old, fully supported database mechanism that Dahan defines as a kind of CQRS since it separates writes from reads. He notes that when doing complex joins to build query results there may be latency problems which this replication will not solve, but it can still solve a throughput problem by adding more slaves.

Another solution Dahan suggests solving a scalability problem is sharding or database partitioning, dividing data in one table across multiple instances of a database using e.g. customer name to distribute over the instances. One advantage this gives is multiple masters, enabling scaling of both the command and the query side. Partitioning is available out of the box from many database technologies and can be implemented with fairly simple code. He notes that multiple masters will not work with cross-record transaction, thus requiring the same partitioning of the business domain as in the solution domain.

One situation where Dahan believes there is a case for a CQRS approach is in high contention domains with a very high and extremely localized load, e.g. a large number of requests competing for one or a few records in a database. One failure scenario is that most transactions start to fail due to concurrency exceptions, locking up database connections and client requests, creating a huge bottleneck. Often this is an overlooked test case during performance tests, when testing scalability commonly the load is created using many requests working on many records instead of all requests targeting only a few records. Even with a perfect implementation of CQRS the bottleneck will show up on the query side, the background process cannot update fast enough, causing the query model to fall farther and farther behind.

Dahan’s solution for this contention problem is to move to a model that is event based using a non-blocking append-only data model which means it’s not affected by contention. This can however introduce a problem since it may prevent some business rules, e.g. an order can only be processed if there is enough inventory of products ordered. This solution therefore needs a more flexible business process and a possible change in the requirements. Using the example with orders, the business process should allow for orders to be accepted without inventory checked. If some products are missing in inventory later on when the order is processed the business has to decide how to handle that situation.

Rate this Article