#28 CQRS Myth Busted: Separating Commands from Queries, Not Databases
One of the most widespread interpretations of CQRS involves using two separate databases for read and write operations. This view has become so popular that it is often considered integral to CQRS.
For a long time, I have wanted to write about a common misconception in software design. Throughout this year, I have seen numerous articles and tutorials about the CQRS (Command Query Responsibility Segregation) pattern that always present it with two separate databases—one for reading and one for writing. It has even been spread by popular tech newsletters with huge followings.
But what if I told you that you don't actually need separate databases to implement CQRS?
In fact, what if I told you that you don't need a database at all to use CQRS?
(╯°□°)╯︵ ┻━┻
To truly understand the concept, let's look at how Greg Young, who originally introduced it, defined it in his blog post.
CQRS is simply the creation of two objects where there was previously only one. The separation occurs based upon whether the methods are a command or a query (the same definition that is used by Meyer in Command and Query Separation, a command is any method that mutates state and a query is any method that returns a value).
Did you notice that the definition does not mention a database, separate tables, or separate databases? That's because it does not matter if you store the data in:
A single database
Read and write databases
Relational or non-relational databases
Text file(s)
CSV
You can keep your data wherever you like, but now you have two ways to interact with it: commands for making changes (write operations) and queries for getting information (read operations):
Write. Represented by commands, which instruct your system to perform operations, thereby changing the system state.
Read. Represented by queries, which retrieve data from your system without changing its state.
To picture the above with the real-world example, imagine that you work on eShop application. There are two business operations:
Preparation of the order (
POST
)Retrieval of new products (
GET
)
These operations can be triggered by calling the API. Then, either command is triggered (preparation of the order) or query is executed (retrieval of new products).
Thanks to the split, if you need to optimize writes or reads, you can do it independently. In the end you have two objects (write and read) where there was previously just one.
Is CQRS that simple? Yes.
So why is it almost always presented with two databases as an integral part? There are two main reasons for this. First, in most systems, the database is the place to store the data (relational or non-relational). Second, in some cases—at some point—it makes sense to physically isolate reads from writes. This way, you can use various database engines that are either optimized for writes or reads. Still, having separate databases is the implementation detail, which will vary based on the specific requirements of each system.
Do you also see the problem with this common misconception?
PS If you are interested in other CQRS myths, there is an excellent article (from 2012) by Jimmy Bogard.