Skip to main content
  1. References/
  2. Architecture Design Basics/
  3. Pattern Taxonomy/
  4. Data Storage & Retrieval/

CQRS

·· 191 words· 1 min

🟠 P1 — Command Query Responsibility Segregation; separate read and write models

Problem #

Read and write workloads have fundamentally different characteristics. Writes need consistency and validation. Reads need speed and flexible query patterns. A single model optimised for one sacrifices the other.

Mechanism #

┌─────────────┐         ┌──────────────┐
│ Write Model  │         │  Read Model   │
│ (normalised, │  event  │ (denormalised,│
│  consistent) │───────→ │  query-opt)   │
│ PostgreSQL   │         │ Elasticsearch │
└─────────────┘         └──────────────┘
      ↑                        ↑
   Commands               Queries
  (mutations)             (reads)
  • Commands (writes) go to the write model, which enforces business rules and consistency
  • An event/projection mechanism synchronises changes to the read model
  • Queries (reads) go to the read model, which is denormalised for fast retrieval

Key Trade-offs #

DimensionBenefitCost
Read performanceOptimised query modelsEventual consistency between models
Write simplicityClean domain logic, no read hacksTwo models to maintain
ScalabilityScale reads/writes independentlySynchronisation complexity
FlexibilityDifferent read models per use caseMore moving parts

Instinct #

CQRS is justified when read and write patterns genuinely diverge. If your reads are simple key lookups on the same data you write, CQRS adds complexity for no gain. If your reads require full-text search, aggregations, or graph traversals on data that’s written relationally, CQRS pays for itself. Often pairs with Event Sourcing.

DDIA 2e Reference #

  • Chapter 11: Derived data, maintaining materialised views
  • Chapter 12: Unbundling databases