← Back to list

Segregation of Responsibilities with CQRS

When CQRS is considered and designed strategically, it can provide significant benefits.

Kağan MURAT, PMP® · 2026-01-16 21:34 · 0 claps · 4.1 min read
#cqrs #cq #segregation #crud-operations
Open on Medium ↗

Segregation of Responsibilities with CQRS

Segregation of Responsibilities with CQRS (The image was generated using AI)

Segregation of Responsibilities with CQRS (The image was generated using AI)

Modern applications have significantly higher user volumes and handle much more traffic compared to legacy systems. This situation necessitates building our processes on different architectural structures. Architectures that are easy to scale when needed and whose performance can be improved efficiently are becoming increasingly prominent.

Traditional architecture is suitable for creating a single data model and performing all read and write operations on it. With this approach, a data access layer is used to perform read, update, and delete operations on a data source.

However, as applications grow, the operations performed on such a data source do not exhibit a homogeneous distribution. They may require a large number of read operations while involving relatively fewer write operations. A system with this type of operating pattern can lead to data inconsistency, performance issues, and security problems.

CQS (Command Query Separation)

The CQRS design pattern is based on the CQS (Command Query Separation) design pattern. The CQS pattern was developed by Bertrand Meyer and was introduced in his 2000 book Object-Oriented Software Construction [1]. The core idea of this pattern is as follows: “A method should be either a command or a query, but not both at the same time.”

The definitions of command and query in this explanation are as follows:

Command: Causes a change in state. Insert, Update, and Delete are operations of this type. It does not return a value and is of type void. In summary, it performs a change but does not return a value.

Query: Does not cause a change in state. Select is an operation of this type. It returns a value. In summary, it returns a value but does not make any changes.

According to the CQS pattern, a method should not both modify state and return a value. These two responsibilities must be executed separately.

A correct command → void SetEmail(string email); A correct query → string GetEmail();

An incorrect example → bool SetEmail(string email); // It causes a state change, which makes it a command, but it also returns a value, which makes it a query. It cannot be both at the same time.

Command and Query Separation with CQS

Command and Query Separation with CQS

CQRS (Command Query Responsibility Segregation)

Developed by Greg Young in 2010, CQRS is a design pattern based on the CQS pattern [2]. Unlike CQS, it applies operations at the object level. In other words, each object is divided into command and query objects. In this way, the operations related to an object are structured vertically.

CQRS, or Command Query Responsibility Segregation, essentially separates command and query operations from each other. This can be interpreted as encapsulating the two types of logic independently.

A traditional flow and the flow provided by the CQRS design pattern are simply illustrated below. In figure (a), commands and queries are processed within the same layer, whereas in figure (b), commands and queries are handled separately through different services.

Traditional Flow and CQRS Flow

Traditional Flow and CQRS Flow

As an example, a CRUD class created for a Product entity and its simplified separation into commands and queries is shown below.

Traditional CRUD Class and CQRS Structure

Traditional CRUD Class and CQRS Structure

When the code above is examined, the operations for adding, updating, and deleting Product (commands) are designed in a separate class, while listing and retrieving by identifier (queries) are designed in a separate class.

A Real-Life Example: Developer and Analyst

In a simple software development process, let there be two main activities:

  • Gathering requirements (Query)
  • Coding (Command)

In a traditional approach:

  • The software developer gathers requirements from the user.
  • The developer goes to the office and implements the code.
  • The software developer is responsible for both querying and updating.

In the approach where responsibilities are separated (CQRS):

  • The analyst gathers requirements from the user.
  • The software developer performs the updates.
  • The analyst is responsible for queries, and the software developer is responsible for updates.

When we consider this example, CQRS clearly defines the responsibilities of the analyst and the software developer. Each focuses on their own area of responsibility. If the coding workload increases, the number of developers can be increased. If the number of user requests grows, the number of analysts can be increased.

What Are the Advantages of Using CQRS?

  • Compliance with the Single Responsibility Principle: The command side focuses solely on write operations, while the query side focuses only on read operations. This enables cleaner and more readable code.
  • Scalability: Two synchronized databases can be used. The database used for write operations and the one used for read operations can be scaled independently based on traffic.
  • Performance: Read operations can focus on constructs such as joins and views, while write operations can focus on normalization.
  • Ease of Maintenance: Since commands and queries are handled separately, maintenance becomes more modular and manageable.

What Are the Disadvantages of Using CQRS?

  • Complexity: More classes and more code are required. The number of layers increases.
  • Learning Curve: For someone newly joining the project, readability and understanding can be challenging.
  • Unnecessary Cost: In simple applications, it may introduce unnecessary overhead and workload.

In conclusion;

CQRS is not a design pattern that must be used in every project. However, when it is considered and designed strategically, it can provide significant benefits. It is well suited for applications with complex business rules, non-homogeneous read/write traffic, and microservice architectures. On the other hand, its use may be unnecessary in simple systems that require rapid development.

[1] https://martinfowler.com/bliki/CommandQuerySeparation.html

[2] https://cqrs.wordpress.com/wp-content/uploads/2010/11/cqrs_documents.pdf


메타데이터
post_id
d288ee12d745
slug
segregation-of-responsibilities-with-cqrs-d288ee12d745
url
https://medium.com/@kaganmurat/segregation-of-responsibilities-with-cqrs-d288ee12d745
canonical_url
https://medium.com/@kaganmurat/segregation-of-responsibilities-with-cqrs-d288ee12d745
author_url
https://medium.com/@kaganmurat
status
ok
fetched_at
2026-07-15 14:18:47