Skip to content

Herman J. Radtke III

The Essence of CQRS

I have been familiar with the concept of Command Query Responsibility Segregation (CQRS) for a while, but did not truly understand its practical application until I read The Log: What every software engineer should know about real-time data's unifying abstraction by Jay Kreps.

When I read articles explaning CQRS, most are like the one on Martin Fowler's Bliki. The concept of separating reads and writes makes sense but the why is lost in a bunch of hand-wavy examples mostly relating to event sourcing. Then I saw this diagram from Jay Krep's article on logs:

writes
writes
reads
reads
Clients
Clients
Serving Nodes
Serving Nodes
writes
writes
Log
Log
Viewer does not support full SVG 1.1

I now understand the essence of what CQRS brings to distributed systems. We can build a service to send writes to something like Kafka and reads to something like Postgres (or any other data store).

writes
writes
reads
reads
Service
Service
Postgres
Postgres
writes
writes
Kafka
Kafka
Viewer does not support full SVG 1.1

The value of this approach is not for the service itself (though it can be helpful), but the rest of the system. Separating commands allows other systems (like Search, Analytics, Monitoring, etc) to read from the same stream of commands.

writes
writes
reads
reads
Service
Service
Postgres
Postgres
writes
writes
writes
writes
writes
writes
writes
writes
Kafka
Kafka
Lucene
Lucene
BigQuery
BigQuery
DataDog
DataDog
Viewer does not support full SVG 1.1