What is CQRS?
CQRS — Command Query Responsibility Segregation — is the architectural decision to use different models, and often different databases, for changing state and for reading state, on the premise that the two have such different requirements that forcing them to share is what creates most of the complexity in growing systems.
Where it came from
The seed is Bertrand Meyer's Command-Query Separation principle from the 1980s — every method should either change state (a command) or return information (a query), never both. Greg Young extended that single-method idea to the architectural level in the late 2000s, arguing that the same separation makes sense for entire models. The pattern came of age in the .NET domain-driven-design community around 2010 and spread from there, often paired with event sourcing.
The mismatch CQRS solves
In a typical CRUD application, a single domain model serves both reads and writes. The User entity carries validation rules and lifecycle logic for changing email and password, and the same shape also feeds the dashboard, the admin page, the search results, and the export job. As the application grows, the read side and the write side want different things: the write side wants strict invariants and a small, focused shape; the read side wants denormalized, pre-joined data optimized for whichever screen is asking. Forcing them to share is the source of slow queries, awkward joins, and code that feels like it is fighting itself.
CQRS makes the split explicit. The write side has commands (CreateOrder, CancelInvoice, PromoteUser) that go through a domain model with all the validation and business rules. The read side has queries that hit denormalized, often pre-computed projections in a store tuned for that read shape — sometimes the same database, sometimes Postgres for writes and Elasticsearch for reads, sometimes Postgres for writes and a column-store warehouse for reporting reads.
The eventual consistency trap
The hardest thing about CQRS in practice is not the architecture — it is the user experience. When write and read sides are separate stores, there is a delay between an action and the read model reflecting it. A user submits a form, sees a success message, navigates to the list page, and the item they just created is not there yet. Solving that requires either (a) accepting and designing for the lag with optimistic UI, (b) making the write transaction also update the read model synchronously where consistency matters, or (c) routing the user's own reads to the write store for a short window. Pretending the lag does not exist is how teams get to "the bug nobody can reproduce."
When the pattern is worth it
CQRS pays off when read and write loads are wildly asymmetric (think a marketplace with millions of reads per write), when the write model is genuinely complex and read shapes are wildly varied (analytics on top of a transactional system), or when the team is already committed to event sourcing and CQRS comes along for the ride. For a typical CRUD product with balanced load, applying CQRS is the kind of architectural decision that pleases architects and burns engineering time on problems that did not need to exist.
At QUANT LAB
We apply CQRS selectively, not as a blanket choice. Trading platforms we build use it for the order management side — the write model is strict, the read model is a denormalized view tuned for the trader's UI, and the two are kept in sync via an event stream. Most SaaS products we ship do not need it across the whole codebase, but often have one or two slices — reporting, search, analytics — where the pattern earns its keep.
The decision is usually made during the discovery phase of a custom build by looking at the actual access patterns rather than imagined ones. If you want a sober review of whether CQRS would help your system or make it worse, book a 30-minute call.
Long-form deep-dives that use this term
All postsBuilding Multi-Tenant SaaS on Postgres RLS
Row-level security patterns for isolating tenant data without separate databases.
Read postInternal Tools Platform Engineering Guide
Architectural patterns for ops dashboards, admin panels, and back-office UIs.
Read postNext.js + Stripe: The Complete Integration Guide
Server Actions, the Payment Element, webhook idempotency, and subscriptions.
Read post
Related terms
CQRS — yes or no for your system?
Half an hour with an engineer is enough to map your read and write loads and tell you honestly whether the pattern would help or hurt.