Skip to content
AI360Xpert

CQRS (Command Query Responsibility Segregation)

CQRS architecture
CQRS architecture

Overview

CQRS stands for Command Query Responsibility Segregation. It is an architectural pattern that separates the data models and APIs used for reading data (Queries) from the models and APIs used for updating data (Commands). This allows you to scale and optimize read and write operations independently.

🧠 Mental model: Think of a busy restaurant. The chefs in the kitchen (Commands) are optimizing for taking raw ingredients and assembling them into meals as fast as possible. The waiters and menus (Queries) are optimized for quickly showing customers what is available. They use completely different tools and systems, even though they represent the same restaurant.

Key Concepts

The Problem with CRUD

In traditional CRUD architectures, the same database and the same data model (e.g., an ORM entity) are used to both read and write data. As a system scales, read traffic usually vastly outpaces write traffic. Furthermore, the way you want to write data (highly normalized to ensure consistency) is often the exact opposite of how you want to read data (highly denormalized so it's fast to query).

The CQRS Solution

  • Commands: Operations that mutate state (Create, Update, Delete). They do not return data (other than success/failure). They run against a "Write Database" optimized for transactions (e.g., PostgreSQL).
  • Queries: Operations that read state. They do not mutate anything. They run against a "Read Database" optimized for fast lookups (e.g., Elasticsearch, Redis, or a denormalized NoSQL database).

Synchronization

Because the read and write databases are separate, they must be synchronized. When a Command updates the Write DB, it emits an event (often via Kafka or RabbitMQ). The Read DB listens to this event and updates its own denormalized views. This introduces Eventual Consistency.

Trade-offs

CQRS allows immense scalability (you can scale read nodes 10x higher than write nodes) and performance (read queries are simple lookups with no joins). However, it drastically increases system complexity. You now have to maintain two different databases, two different models, and complex message brokers to sync them. It forces the UI to deal with Eventual Consistency (a user might update their profile, refresh the page, and see their old profile for a few seconds).

Interview Tips

  • Only suggest CQRS for highly complex domains or systems with extreme read/write asymmetry (e.g., Twitter: writing a tweet is a Command, reading a timeline is a Query).
  • Always pair CQRS with Eventual Consistency in your explanation, as syncing the read and write models is asynchronous.
  • CQRS is frequently paired with Event Sourcing (where the Write DB is just an append-only log of events).

Summary

  • CQRS separates the system into Commands (writes) and Queries (reads).
  • It solves the problem where read and write workloads require fundamentally different data models and scaling.
  • Commands use a normalized Write Database; Queries use a denormalized Read Database.
  • The two databases are synchronized asynchronously via events.
  • CQRS provides massive scalability but introduces high complexity and Eventual Consistency.