The Command and Query Responsibility Segregation (CQRS) Design Pattern


The ‘Command and Query Responsibility Segregation’ (CQRS) design pattern is based on the “Command-Query Separation” (CQS) principle from the book “Object-Oriented Software Construction“ by Bertrand Meyer (1988) and was first mentioned by Greg Young and Udi Dahan in 2010.

This pattern has produced a lot of excitement and hype but the principle behind it is very simple.

As the demands on command methods (any method with write access that mutates state) are usually very different to those on query methods (any method with read access that returns a value), it makes sense to separate these two groups. This would naturally mean different services but might also mean different models.


public interface BookService {
    public Book getBook(int bookId);
    public Book findBook(String isbn);
    public void createBook(Book book);
    public void updateBook(Book book);
    public void deleteBook(int bookId);

Using CQRS we could break this service down into two smaller services:


public interface BookWriteService {
    public void createBook(Book book);
    public void updateBook(Book book);
    public void deleteBook(int bookId);


public interface BookReadService {
    public Book getBook(int bookId);
    public Book findBook(String isbn);

Doing so would enable us to make interesting architectural changes. We could for example separate the hosting of the two services. The write service could be hosted on one server while the read service could be hosted on many (ten for example).

This is especially true for the chosen example as the state of books rarely changes; there are few cases where a book would need to be updated.

That is the key concept of the ‘Command and Query Responsibility Segregation’ (CQRS) pattern: Take a traditional service and separate it into its read and write parts.

Taking the pattern further

Although the pattern itself is very simple it opens up interesting possibilities.

The standard CRUD (Create, Read, Update, and Delete) model looks something like this:


Applying the CQRS design pattern we can separate the service interface and create two different models. One for reading and one for writing:


Especially in cases of complicated domains this is an improvement on the traditional model as it enables the simplification of both models.

Based on the example above the BookWriteService and BookReadService can be split into:

CreateBookCommand (implements Command interface)
UpdateBookCommand (implements Command interface)
DeleteBookCommand (implements Command interface)
GetBookQuery  (implements Query interface)
FindBookQuery (implements Query interface)

One problem that appears if the two models are running in different JVMs or on different hardware is keeping the data synchronized. In a case like this where  models share the same database, it could be used to communicate between the two.

Going one step further we can add a separate data store for reading:


Here the full power of CQRS becomes visible:  By separating the read and write data store steps the read operations can be optimized to the maximum on a software (de-normalization) and hardware level (adding extra servers).

The synchronization of the read and write data is done using an event handling mechanism.

The RDBMS would act here as the master database and the Read Data Store(s) would act as slave(s). The Read Data Store(s) could be completely rebuilt at any time using the RDBMS data.

For the read operations this architecture would be ideal for No-SQL databases (e.g. MongoDB, CouchDB, etc.) or OLAP-databases.

When to use the pattern

Though the concepts of CQRS are more and more widespread, big projects where it was successfully implemented are still quite rare. Martin Fowler wrote in July 2011:

“It’s also true that we haven’t seen enough uses of CQRS in the field yet to be confident that we understand its pros and cons. So while CQRS is a pattern I’d certainly want in my toolbox, I wouldn’t keep it at the top.”

Of course time has passed since 2011 but reference implementations are still hard to find.

When applying CQRS it should be taken into consideration that it might not be applicable to the system as a whole, so each portion of the system (“bounded context”) needs to be examined individually.

Event Sourcing and Task Based UI

Command and Query Responsibility Segregation can be applied on its own. However very often it is linked to further patterns. Here is a short summary of two of them:

Event Sourcing:

Event Sourcing can be described as the “capture of all changes to an application state as a sequence of events.” This represents a major shift in the way data is stored. Traditionally the contents of a database represented the present state of the application. A History of the changes was rarely available; at most a field “last modified date”.

Using Event Sourcing every change (event) is stored separately meaning that the data’s history is preserved. This makes for a much richer data source which, for example, could enable the generation of statistics on changes or the reconstruction of past states.

Link with CQRS: The main problem with Event Sourcing is that querying is complicated because it entails going through all the entries in the event log. By separating writing and querying CQRS supports the use of Event Sourcing on the write side.

Task Based UI:

Traditionally UI tasks are handled using DTOs. The DTO would be retrieved from the server and used to set up the state of the User Interface. The user would then make some changes and click on save.

A DTO (usually the same one) would then be sent back to the server. The problem with this method is that the intention of the user gets lost. In Task Based UI the initial behavior is the same (a DTO is retrieved from the server) but then instead of sending a DTO the application sends back messages (“commands”). This gives much more information about the behavior of the user.

Link with CQRS: Having two different models for command and query enables the use of Task Based UI.

Further study

There are a lot of resources available for CQRS. Most of them somehow combine “Command and Query Responsibility Segregation”, “Event Sourcing” and “Task Based UI”.

This page gives a nice overview of CQRS. The code snippets are in C# (.NET):

CQRS sample code in Java (using Spring and JPA) :

Axon claims to be a “CQRS Framework for Java” (I have not tested it so cannot really comment):



  1. Martin McNulty

    Hi Peter

    Thank you for the compliments.

    When using CQRS it makes sense to combine it with Event Sourcing as this gives the application a richer Data Source.

    When using Event Sourcing the problem doesn’t occur because only new events get stored to the write database (to express this differently: only the data “delta” gets written to the database), meaning the previous state of the data is irrelevant.

    If you choose not to use Event Sourcing you could either query the read model (though in theory it would be nicer not to, I don’t see any huge problem in doing so) or enrich events at creation so as to contain all the data needed later on (this would of course mean fatter events).

    Yes in both cases you would need a slightly thicker application service but nothing prohibitive.


  2. Peter


    Great article, thanks! Clear and simple.

    There is one thing that makes CQRS difficult for me to understand and that is getting the data that is required for building a command.

    When building the model “old” style, I feel the need to use data that is considered read for building data to execute a write.

    This prevents application (as in “not model”) programmers from knowing relations that can be set in the model and simplifies the amount of parameters that need to be passed to the model.

    But how is this with CQRS?

    There is no reference between the read and write part, so this means application programmers need to build a complete set of data from the application?

    This will require a “thicker” application service?

    How do you manage this?

    Thank you,


Hinterlasse eine Antwort

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind markiert *