When to use the CQRS design pattern?
Asked Answered
B

14

82

My team and I have been discussing using the CQRS (Command Query Responsibility Segregation) design pattern and we are still trying to asses the pros and cons of using it. According to: http://martinfowler.com/bliki/CQRS.html

we haven't seen enough uses of CQRS in the field yet to be confident that we understand its pros and cons

So what do you guys think, when does a problem call for using CQRS?

Bombazine answered 11/1, 2012 at 14:14 Comment(2)
Darren Cauthon does a nice presentation on CQRS and Event Sourcing, including the drawbacks - Google says it's available here, but I can't verify that through our firewall.Gargle
he personally hasn't seen it in the fieldAnnmarie
N
81

CQRS is not a pattern that encompasses the whole application.

It is a concept that builds on Domain Driven Design (DDD). And an important strategic concept of DDD is the so-called Bounded Context.

In a typical application there are multiple bounded contexts, any of which can be implemented the way it makes sense. For instance

  • User Management -> CRUD
  • Invoicing -> CRUD
  • Insurance Policy Management (the Core Domain) -> CQRS
  • ...

This probably doesn't answer your question but it might give a little more insight into the topic. To be honest, I don't think it can be answered at all without considering a project's specifics, and even then there is rarely something like a definite best practice.

Nahuatlan answered 11/1, 2012 at 17:1 Comment(9)
Disagree with the statement that CQRS is not a pattern and that, once you decide on using it, will often encompass the whole application. CQRS is an architectural pattern, not a top-level architecture. Thus, you must evaluate whether to apply it on every specific bounded context. See cqrsjourney.github.com and read the 2nd Reference chapter.Gertrude
@GrigoriMelnik maybe the first sentence of my answer is not clearly formulated (I'm no native speaker as well). As far as I can tell, I'm saying the same as you do. CQRS should be applied on a bounded context basis, not across a whole application.Nahuatlan
@DennisTraub Actually I think your sentence is properly formulated and it's Grigori Melnik that interpretes it the wrong way.Arciform
While it's hard to define terms like this, I'm not sure where the part about it building on DDD comes from? To me they are not tied together at allAfterburner
"Insurance Policy Management (the Core Domain) -> CQRS" doesn't really say much without any example...Derosier
following will be a good resource to followup on implementations blog.sebastian-daschner.com/entries/…Playtime
I'm just re-reading this and I think what you really mean here is not the real reason for using CQRS. It's about CRUD and non-CRUD (task-based UIs). And you don't need to use CQRS to implement task-based UIs. You can use only commands without any queries and without CQS too! Just command-like pattern alone, you don't need to separate commands from queries to implement task-based UIs.Derosier
The real reason for using CQRS is here: softwareengineering.stackexchange.com/questions/336855/…Derosier
But yeah people often see it as the only way to use when dealing with task-based UIs which I think is wrongDerosier
T
41

Well CQRL critics may say that CQRS is complicated and that might be true.

Of course, it's adding overhead developing a simple CRUD application in the CQRS style, so I'd consider using CQRS only in the following cases:

  1. Large team - You can split development tasks between people easily if you have chosen CQRS architecture. Your top people can work on domain logic leaving usual stuff to less skilled developers.
  2. Difficult business logic - CQRS forces you to avoid mixing domain logic and infrastructural operations.
  3. Scalability matters - With CQRS you can achieve great read and write performance, command handling can be scaled out on multiple nodes and as queries are read-only operations they can be optimized to do fast read operations.
Tentmaker answered 11/1, 2012 at 14:32 Comment(2)
I'm not so sure that having a distributed team would come into my thoughts when considering CQRS. Any layered/multi-tiered application can be broken down nice segregated tasks.Countermove
complicated to understand or complex ? you should make the distinction clearer about these critics. IMO it simplifies your life on many aspects and yeah it's not what you learn at school, so there are some additional efforts to be done to understand it.Goldbrick
A
18

When you have a complex or hard business domain and:

  • with event sourcing; you want a nice way of testing logic
  • with event sourcing; you want to prove your behaviours through testing and reasoning
  • you have multiple clients, or consumers, of your domain service (not just single web server)

OR you have users that need to act on common data:

  • and you want to formalize the data merge concepts of your domain
  • or you want to apply logic for merging events

OR you have scalability requirements:

  • you apply the pattern as a denormalization pattern that removes bottlenecks
  • you want to scale horizontally and not vertically

OR you have performance problems (other side of scalability):

  • e.g. you need to migrate your architecture towards an event driven architecture - CQRS as a pattern is a good stepping stone.

OR you have a team that is physically disjunct:

  • e.g. parts of your team is in another country
  • or it's hard to get face-to-face communication, so you want to decouple the read models from the write-side of things (sagas, domain, CRUD)

It's not CQRS that's overly complicated, it's computers that are.

Annmarie answered 20/1, 2012 at 15:20 Comment(1)
See comment on @MairbekKhadikov's answerCountermove
V
17

When to use the CQRS design pattern?

The CQRS architecture pattern could be used when it is difficult to query from repositories all the data that users need to view. This is especially true when UX design creates views of data that cuts across several aggregate types and instances. The more sophisticated your domain, the more this tends to be true.

When it is unsuitable to compromise on UX design, using CQRS attempts to mitigate the problems associated with other solutions, such as:

  • requiring clients to use multiple repositories to retrieve all aggregate instances; or
  • the design of specialized finders on various repositories to gather disjointed data using a single query.

To summarize: Use CQRS when its difficult to query from repositories data users need to view, which tend to happen the more sophisticated your domain is.

Virgiliovirgin answered 30/10, 2014 at 10:9 Comment(2)
You don't necessarily need CQRS for that, materialized views will be usually enough if the data is difficult to query.Tempi
@Tempi Materialized views require that the data is stored in the same database. This is often not the case in microservice architectures where CQRS often is paired with event sourcing.Virgiliovirgin
S
7

In real world scenario CQRS might be useful when you have front end/web service client which needs lots of data from multiple domains and retrieval of these data from database takes long time.

In such case you might consider creation of separate read model which will be faster to develop and might have faster execution time.

Siliqua answered 6/6, 2017 at 9:25 Comment(0)
P
5

Following are the reasons to use CQRS:

  1. Scalability (read exceeds the write, so does the scaling requirements for each differs and can be addressed better)
  2. Flexibility (separate read / write models)
  3. Reduced Complexity (shifting complexity into separate concerns)
  4. Concentrate on Domain / Business
  5. Facilitates designing intuitive task-based UIs
Psychochemical answered 11/1, 2012 at 14:15 Comment(0)
L
5

Well, there is no straightforward answer to your question, but I would like to give you some real-world examples of how CRQS could be implemented which could help you figure out how it could be used in your application,

1. Instagram

We often see Instagram stories/reels etc. These stores are read-intensive, it's better to have a separate read-only database for such data. The outer world can only deal with that particular DB for rendering stories in your friend's timelines, doing so the system does not need to bother the main DB where major business-intensive information is stored.

2. Amazon

When an order is placed, the order service emits an event, this event is subscribed by other services out of which one could update denormalized Read-Only DB, and other services(let's say messaging service) could simply pick up normalized information like userId, ordered, etc, etc from Read-only DB and proceed with email processing for order confirmed

Lyndialyndon answered 12/11, 2021 at 7:54 Comment(0)
G
3

Below are some scenarios where the CQRS Pattern fits perfectly:

  • Large projects where high performance is required and independent scalability is required.
  • In the applications where business logic is complex. In such a case, you can separate your reads from write to make it more simple.
  • If you want parallel development where one team can work on the read models & other team works on write models.

Read this Article to understand more about CQRS Pattern.

Giantess answered 4/10, 2021 at 6:57 Comment(0)
P
2

Use it when :

  1. Have a complex domain and need to understand domain by commands
  2. Application load with read and write differes
  3. Want to scale read operations at any point of time

https://learn.microsoft.com/en-us/azure/architecture/patterns/cqrs#when-to-use-this-pattern

Politi answered 25/10, 2020 at 8:54 Comment(0)
B
1

If you are seeing that the problem domain doesn’t fit well into more generic architecture or you are experimenting with domain-driven design, I’d recommend you to give CQRS a shot.

It is a powerful pattern, which might give you good exposure to the problem domain as well as solve some technical and infrastructural challenges. But it is worth keeping in mind that it will come with its price and due to conceptual differences with other architectures, it will require a mental-model shift.

CQRS: Intro

Broadsword answered 13/1, 2020 at 6:14 Comment(0)
D
1

Everyone explained why you need to use CQRS, but let's talk about why NOT use it:

So, one of the main characteristics of CQRS application is that data will be eventual consistency. This means the data that the query retrieves may not always be latest data because of the synchronization process that updates the data. When processing those requests, it can cause a certain lag between command and queries. If you are going to use CQRS you must be aware of that and in the case of your business needs to have strong consistency, you should not use CQRS. (Banking applications i.e.)

enter image description here

Daytoday answered 18/11, 2022 at 12:22 Comment(0)
N
1

I have a different take on the subject to everyone else. I literary build everything using CQRS. Even the simple CRUD applications.

However, I simplify it a lot and make things flexible.

Here is why and how:

  1. It is built on top of Domain Drive Design (DDD) concept.
  2. I always separate things into Queries and Commands.
  3. Each are handled by either QueryHandler or CommandHandler.
  4. Query and its Response and QueryHandler live in the same class and represent a single small self-contained functionality.
  5. They are very easy to unit test.
  6. I start with a single storage for both queries and commands and separate them if needed. Usually have it all in SQL Server and move some stuff to Cosmos DB (noSQL) or Redis for queries if needed.
  7. It enforces consistency and makes it easy to group functionalities in the project.

In my case my queries and commands are consumable by API, Blazor, Azure Functions etc keeping the consumers as thin as possible.

So in my humble opinion I find it way more productive to build features using CQRS with a single storage than doing CRUD that tend to grow quickly and become cluttered.

The hardest part is when you have to switch to read storage and write storage and you have to keep them in sync. There are mechanism out there to make it happen but by the time you reach this point you will be able to solve most of your performance issues with things like optimizing your SQL in queries or even in-memory caching.

After 11 years of posting this question you probably made up your mind but for anyone seeing this question I recommend to check out this CQRS implementation repo on github that uses a single storage. It's .NET 7 specific but it can applied to any language out there.

Nauru answered 27/4, 2023 at 14:20 Comment(0)
S
1

In short, use CQRS pattern only if the application velocity is so important that you're ready to sacrifice time and money on it, and immediate consistency is not desired.

They say CQRS brings the following values:

  • Scalability: You can have different Database for read and write.
  • Single responsibility.
  • Decoupling.
  • Testability.
  • Security.
  • Complexity removal.
  • Different teams: For example, one team works on commands and another works on queries.

In my opinion, scalability is the most prominent benefit of CQRS, other pros are arguably not proven or weak. I mean, single responsibility or decoupling or separate-team are poorly based on how do you interpret your design. You can have any other architecture and you still benefit from “testability” and “security”. “decoupling” and “removal Complexity” doesn’t happen as those functionalities are merely moved from one place to another; a complex query is always remained complex; you just change its place. As another example, in practice you won’t see two separate teams are working on a same module (one for commands and one for queries).

Moreover, CQRS does not add any value mentioned above except when you decide to have two databases (at least) in order to query from one and execute command on the other. This way, you removed the database read/write bottleneck in favor of gaining faster response, yet brought disadvantages to your code such as:

  • Eventual consistency: As query-database need to be aligned with the latest changes happening in the command-database, and it takes time to update query-database accordingly which may not suitable for some crucial situations (e.g., real-time payment or trade).
  • Complexity: This is not the end of the story. Your dilemma is just about to begin. CQRS doesn’t improve application’s velocity if you immediately apply each and every incoming change-request into the query-database Hence, you need to utilize a message broker to channelize and priorities changes toward query-database. You also may need a mechanism to apply those changes in batch; otherwise, the query-database performance degrades.
Storer answered 19/5, 2023 at 8:43 Comment(0)
X
0

With regards to implementing CQRS, I like the idea of separating read models when you have a front end/web service client requiring lots of data from multiple domains, and I would like to try it. My primary reason for wanting to try it is due to the issue with 'slowness'in development and execution processes; especially when it comes to handling large data sets, or 'big data'. I'm looking at all the various options available in reducing complexity(ies), adding scalability, resiliency, and flexibility to a hybrid architecture.

Xanthochroid answered 27/10, 2019 at 22:14 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.