devxlogo

Command Query Responsibility Segregation Explained

Command Query Responsibility Segregation Explained
Command Query Responsibility Segregation Explained

Command Query Responsibility Segregation (CQRS) is a software architecture pattern that separates “reading data” from “writing data.”

That’s the entire idea in one sentence.

But to really understand it, you need to see why it exists and how it changes system design.

Command Query Responsibility Segregation (CQRS) — Explained Clearly

The Core Idea

CQRS splits system operations into two categories:

Type Purpose Example
Command Changes data Create order, update profile
Query Reads data Get order details, list users

Commands modify state.
Queries only return data.

In CQRS, these two responsibilities are handled separately, often with different models, services, or even databases.

A Simple Example

Imagine an e-commerce system.

Without CQRS (traditional architecture)

One model handles everything:

OrderService
   ├── CreateOrder()
   ├── CancelOrder()
   ├── GetOrder()
   ├── GetOrdersForUser()

One database schema must support:

  • writes
  • complex reads
  • reporting queries
  • dashboards

This becomes messy and slow at scale.

With CQRS

Commands and queries are separated.

Command Side (writes)
    CreateOrderCommand
    CancelOrderCommand

Query Side (reads)
    GetOrderQuery
    GetOrdersForUserQuery

They may even use different databases.

Commands → Write Database
Queries  → Read Database (optimized for fast reads)

The Key Principle

A method should either:

  • change state (command)
    OR
  • return data (query)

But never both.

Example:

Bad design:

getUserAndUpdateLastLogin()

CQRS design:

GetUserQuery
UpdateLastLoginCommand

Each does one thing.

What Happens in a CQRS System

Step 1 — Command

User acts:

PlaceOrderCommand

Command handler:

OrderCommandHandler

This:

  1. Validates request
  2. Updates the write database
  3. Emits event (optional)

Step 2 — Read Model Update

The system updates a read model optimized for queries.

Example read database:

OrdersView
UserOrderSummary
ProductSalesStats

Step 3 — Query

User dashboard asks:

GetOrdersForUserQuery

The query reads from the read model, which is optimized for fast retrieval.

See also  Five Decisions That Shape a Scalable Monolith

Why CQRS Exists

Traditional systems struggle when:

  • Reads greatly outnumber writes
  • Queries are complex
  • Scaling becomes difficult

Separating responsibilities lets you optimize each side independently.

Example:

Write Side Read Side
normalized relational DB denormalized query DB
strict validation fast retrieval
transactional cached / replicated

Real-World Example

Imagine Amazon orders.

Command side

Handles:

CreateOrder
CancelOrder
ReturnOrder
UpdateShippingAddress

These must be strongly consistent.

Query side

Handles:

Order history
Recent purchases
Tracking page
Customer dashboard

These need to be fast, not necessarily transactional.

So Amazon might maintain special read models like:

UserOrderHistoryView
RecentOrdersCache
ShippingStatusView

When CQRS Is Usually Used

CQRS is common in:

Typical tech stack example:

Commands:
API → Command Handler → Write DB

Queries:
API → Query Service → Read DB

Often combined with:

  • Event Sourcing
  • Kafka
  • Message queues

Benefits of CQRS

1. Performance

Reads and writes can scale independently.

Example:

Write DB: PostgreSQL
Read DB: Elasticsearch

2. Simpler Models

The write model focuses on business rules.

The read model focuses on fast queries.

3. Flexible Read Models

You can create multiple read views:

ProductView
SalesDashboard
InventoryView

Each is optimized for a specific query.

Tradeoffs (Important)

CQRS adds complexity.

Common downsides:

1. More moving parts

You now maintain:

2. Eventual consistency

Sometimes the read model updates after the write.

Example:

User places order
Dashboard updates 200ms later

3. Overkill for small apps

For simple CRUD apps:

Controller → Service → Database

is usually better.

Quick Mental Model

Think of CQRS like a restaurant.

Kitchen (Commands)

Handles actions:

Cook burger
Prepare salad
Bake pizza

Waiter / Menu (Queries)

Handles information:

What’s on the menu?
What’s today’s special?
Where is my order?

The kitchen and the waiter serve different responsibilities.

See also  How to Design Resilient Cross-Region Database Architectures

One Sentence Summary

CQRS separates systems into two parts:

  • Commands → change data
  • Queries → read data

This allows each side to be optimized, scaled, and modeled independently.

sumit_kumar

Senior Software Engineer with a passion for building practical, user-centric applications. He specializes in full-stack development with a strong focus on crafting elegant, performant interfaces and scalable backend solutions. With experience leading teams and delivering robust, end-to-end products, he thrives on solving complex problems through clean and efficient code.

About Our Editorial Process

At DevX, we’re dedicated to tech entrepreneurship. Our team closely follows industry shifts, new products, AI breakthroughs, technology trends, and funding announcements. Articles undergo thorough editing to ensure accuracy and clarity, reflecting DevX’s style and supporting entrepreneurs in the tech sphere.

See our full editorial policy.