What is CQRS?
Table of Contents
Let's assume the following situation:
- You are building a developer portfolio site called
devfolio. - In
devfolio, developers can connect theirGitHubandLinkedInaccounts and retrieve information from those accounts. - Both sites have information such as
account name,profile picture,bio,registered websites, etc.
As a web developer, you would create a conceptual data model called social_profile_info
and build APIs to CRUD it.

The variables from Github's API and Linkedin's API may differ.
(This is entirely different from the actual APIs.) When the product was launched, responses came as shown above,
and after receiving them, the server transformed the variable names and stored the information.
Then one day,
- The variable names in the API provided by
Githubchanged.
So an error occurred on devfolio's server that uses the API provided by GitHub.

You modify the server code and redeploy.
The site gets positive reactions after deployment, and now,
- You can connect accounts from
Discord,Slack,Rocket Punch, etc., in addition toGithubandLinkedin.
API modifications become more frequent, and every time there's a change, the feature stops working, and in severe cases, the site goes down. You come up with the following solution:
- What if we update the account information with the raw JSON response as-is, and then extract only the necessary information when displaying it on the website?
CQRS emerged to separate the responsibilities of database updates and reads like this.
CQRS (Command Query Responsibility Segregation) is a pattern that separates
Command, which handles CUD (Create, Update, Delete) logic,
from Query, which handles Read logic.
In the example above, we can illustrate this by separating updating each account's information in the database as a Command
and displaying each account's information in the service as a Query.
In the example, we implemented it by separating the write and read data models within the same database, but you can also completely separate the databases themselves.
For example, you could use MySQL for the write-only database and Elasticsearch for the read-only database.

In such cases, since the Command and Query databases are different,
Event Sourcing is often used to maintain consistency (data synchronization) between them.
Event Sourcing is a method where an Event is triggered whenever a Command comes in, and the Query reads that Event to update the data.
Typically, a publish/subscribe pattern is used where these events are stored in a queue and the Query reads them to update the data.
For information on the Pub/Sub pattern, I've covered it in a WebSocket-related article. :)
CQRS has the following advantages:
- By separating
CommandandQuery, changes toCommandlogic don't affectQuerylogic. - As in the case above, even if various types of writes come in, you don't need to change the
Commandlogic, allowing flexible extension. - Since
CommandandQuerylogic are separated, it's easier to optimize each independently.
CQRS has the following disadvantages:
- Since
CommandandQuerylogic are separated, when using an ORM optimized for CRUD, it actually increases complexity by adding more code. - If
Event Sourcingis implemented asynchronously, data updated by Command is not immediately reflected in Query. (It takes some time to be reflected.)
Due to these pros and cons, CQRS is not suitable for all services. However, for specific services, applying CQRS can significantly reduce complexity. Here are examples of services where CQRS should be applied:
- When the number of reads is much higher than writes and you need to optimize read logic, you can separate them.
- When business rules for writes change frequently, you can use CQRS to reduce complexity.
- In Microservice Architecture, you can use CQRS to separate data models for each service.