In a traditional application, both data modification and data retrieval are handled by the same components. This can lead to bottlenecks when the application needs to scale up because all traffic has to go through the same components.
CQRS is a design pattern that stands for Command Query Responsibility Segregation. It can help you build systems with fast data reads and predictable performance. But it’s not a silver bullet – it only helps in certain situations, primarily when your reads are more expensive than your writes.
Introduction to CQRS
The term “CQRS” is an acronym for “Command Query Responsibility Segregation” developed by Greg Young. It is a software design pattern that separates data modification from data retrieval. The goal of CQRS is to improve the performance and scalability of an application by allowing the two operations to be performed independently. The separation occurs based on whether the interaction is a command or a query.
Command – This can be defined as the change in the state of an object or entire system (sometimes called modifiers or mutators).
Query – return results and do not change the state of an object.
The key distinction between commands and queries is that commands always mutate data while queries never do; this allows us to keep them side-by-side without worrying about consistency issues between the two types of objects.
The queries will only contain the methods for getting data. From an architectural point of view, these would be all methods that return DTOs that the client consumes to show on the screen. The DTOs are usually projections of domain objects. It is possible to introduce a new way of projecting DTOs. You can bypass the domain model and get DTOs directly from the data storage using a read layer.
When an application is requesting data, this could be done by a single call to the read layer which returns a single DTO containing all the needed data. Since the read side has been separated the domain is only focused on the processing of commands. Now the domain objects no longer need to expose the internal state.
CQRS is often used in conjunction with Event Sourcing, another software design pattern. Event Sourcing ensures that all changes to an application’s state are stored as a sequence of events, which can be used to reconstruct the current state at any point in time. Together, these patterns provide a powerful toolkit for building scalable and maintainable applications.
How does CQRS work?
In a traditional CRUD system, when a user interacts with the system, a request is sent to the server which updates the database accordingly. However, in a CQRS system, the user’s interaction is first routed to a Command Handler. This Command Handler then validates that the user has permission to make the requested change and updates the Command Model accordingly. The updated Command Model is then persisted to the Event Store.
One advantage of this separation of concerns is that it can make your system more scalable. For example, if you have a lot of reads but not as many writes, you can scale your query Handler horizontally without affecting your Command Handler.
- Maximize the application performance
- Highly Scalable
- Improves Security
- Supporting the CQRS pattern requires expertise in a variety of database technologies.
- Using the CQRS patterns means that more database technologies are required hence there is a more inherent cost either in terms of hardware or if a cloud provider is used, utilization expense.
CQRS partitions the internals of your application into a read and a write side, allowing you to design and optimize the two paths independently.