When to use the CQRS design pattern?
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.
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.
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:
- 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.
- Difficult business logic - CQRS forces you to avoid mixing domain logic and infrastructural operations.
- 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.