Home/Learn/System Design/CQRS (Command Query Responsibility Segregation)

CQRS (Command Query Responsibility Segregation)

Advanced
Architectural Patterns

CQRS separates read (query) and write (command) models into different data stores optimised for each. Writes go to a normalised DB; reads come from a denormalised, pre-computed view.

Overview

In traditional architectures, the same data model serves both reads and writes. This works until read and write patterns diverge significantly. CQRS splits the architecture into a Command side (handles creates, updates, deletes — writes to a normalised database) and a Query side (handles reads — reads from a denormalised, pre-computed view optimised for specific queries). The two sides are connected by an event bus or change-data-capture pipeline: when the command side writes, it emits an event; the query side consumes the event and updates its read model. CQRS enables independent scaling (reads vs writes), optimised data models (normalised for consistency, denormalised for performance), and different technology choices per side (SQL for writes, Elasticsearch for search, Redis for dashboards). The trade-off is eventual consistency between the write and read models, plus additional complexity in maintaining two data stores.

CQRS Architecture

Commands modify state and go to the write model. Queries read state from a separate, optimised read model. Events propagate changes from write to read side.

Conceptual — CQRS architecture diagram
// CQRS architecture
//
//  Client
//   │ Command (write)          │ Query (read)
//   ▼                          ▼
// ┌──────────────┐        ┌──────────────┐
// │ Command Side  │        │  Query Side   │
// │ (Write Model) │        │ (Read Model)  │
// │ OrderService   │        │ OrderView     │
// └──────┬───────┘        └──────▲───────┘
//        │ write                  │ read
//        ▼                        │
//  ┌──────────┐  event    ┌──────────┐
//  │ Orders DB │ ────────►│ Read DB   │
//  │(PostgreSQL)│ (Kafka)  │(Elasticsearch)│
//  └──────────┘           └──────────┘
//  (normalised)           (denormalised, fast queries)

// Write model: normalised, enforces business rules
// Read model: denormalised, optimised for UI queries
// Event bus: propagates changes from write → read

Implementation

The command handler validates and persists the write. An event listener updates the read model. The query handler reads from the optimised view.

Java — CQRS command, event, and query handlers
// Command handler — write side
@Service
public class OrderCommandService {
    private final OrderRepository orderRepo;
    private final KafkaTemplate<String, OrderEvent> kafka;

    public String placeOrder(PlaceOrderCommand cmd) {
        Order order = Order.create(cmd);
        orderRepo.save(order);  // write to normalised DB
        kafka.send("order-events", order.getId(),
            new OrderPlacedEvent(order));  // publish event
        return order.getId();
    }
}

// Event consumer — updates read model
@Component
public class OrderReadModelUpdater {
    private final ElasticsearchClient esClient;

    @KafkaListener(topics = "order-events")
    public void onOrderEvent(OrderEvent event) {
        OrderView view = OrderView.from(event);
        esClient.index(i -> i.index("orders").id(event.getOrderId()).document(view));
    }
}

// Query handler — read side
@RestController
public class OrderQueryController {
    @GetMapping("/api/v1/orders/search")
    public List<OrderView> search(@RequestParam String query) {
        return esClient.search("orders", query); // fast, denormalised
    }
}

Key Points to Remember

  • 1CQRS separates write (command) and read (query) into different models and stores.
  • 2Write model: normalised, enforces business rules. Read model: denormalised, optimised for queries.
  • 3Events propagate changes from write to read side — eventual consistency.
  • 4Enables independent scaling: more read replicas for high-read workloads.
  • 5Use CQRS when read and write patterns are vastly different — not for simple CRUD apps.

Interview Questions

Sign in to ask Aria
1

What is CQRS and when should you use it?

EasyTCS
2

How does the read model stay in sync with the write model?

MediumAmazon
3

What are the trade-offs of CQRS over a traditional CRUD architecture?

MediumGoogle
4

How does CQRS relate to event sourcing?

HardFlipkart
5

Design a CQRS-based search system for an e-commerce product catalog.

HardNetflix

Ask Aria about CQRS (Command Query Responsibility Segregation)

Your personal AI tutor — ask anything about this concept

Revision Status

Personal Notes

Sign in to save personal notes for this topic.

Discussion

Sign in to join the discussion.

Loading discussion…