Background
Architecture Patterns

What is CQRS?

Command Query Responsibility Segregation is a pattern that separates the code for updating data from the code for reading data.

Instead of one model doing everything, you split your system into two expert halves.

The Core Difference

Switch between Traditional (CRUD) and CQRS architectures to see how the data flows change.

person User
Write/Read
arrow_forward
Data
arrow_forward
Unified Model
Domain Logic
Data Access
database

Single Database

In CRUD, the same object model is used to read and write. Complex logic can make this model bloated and slow.

person User
Command arrow_forward

edit_note Write Model

Optimized for validation & complex business rules.

database Write DB
sync Eventual Consistency
Query arrow_back

table_view Read Model

Optimized for fast lookups (e.g., flat DTOs).

database Read DB

CQRS separates concerns. The Write side handles complexity. The Read side is fast and simple. They sync asynchronously.

How it looks in Code

In a traditional system, a "Service" class often grows huge, mixing logic. In CQRS, we break it down into focused handlers.

CreateOrderCommand.ts
// CQRS: Write Side (Command)
class CreateOrderHandler {
  constructor(private repo: OrderRepository) {}

  async execute(command: CreateOrderCommand): Promise<void> {
    // 1. Heavy Validation Logic
    const product = await this.repo.findProduct(command.productId);
    if (product.stock < command.quantity) {
       throw new Error("Out of stock!");
    }

    // 2. Domain Logic (Change State)
    const order = new Order(command.userId, command.items);
    product.decreaseStock(command.quantity);

    // 3. Persist
    await this.repo.save(order);
    
    // No return value. Intent is "Do this".
  }
}
Interactive Demo

Experience Eventual Consistency

In CQRS, the read model might lag behind the write model by milliseconds or seconds. Try updating the "Official Price" (Write) and watch the "Public Board" (Read) catch up.

edit_note

settings Admin Panel (Write Model)

Vintage Mechanical Keyboard
$

Writes to Primary Database

visibility

public Public Marketplace (Read Model)

Synced
Market Price
$150

Reflects data in the Read DB (e.g., ElasticSearch/Cache).

Lag simulated: 1-3 seconds

Is CQRS Right For You?

check_circle Why it helps

  • scale

    Independent Scaling

    Scale read servers (cheap, many) separately from write servers (expensive, complex).

  • speed

    Optimized Schemas

    Read DB can be "flat" (no joins needed) for instant data retrieval.

  • security

    Security

    Easier to ensure only specific "Command" objects can modify data.

warning The Challenges

  • hub

    Complexity

    You now maintain two models and a synchronization mechanism. Overkill for simple apps.

  • hourglass_empty

    Eventual Consistency

    Users might not see their own changes immediately. Requires UI handling (spinners, optimistic updates).

Practical Decision Checklist

High Read/Write disparity?
Complex Business Rules on Write?
Team familiar with Event Driven?

"If your domain is simple (CRUD), CQRS adds complexity for no gain. If your domain is complex or high-scale, CQRS simplifies the difficult parts."