In a cloud-native application, why might a team split the write side and read side of a service into separate models using CQRS (Command Query Responsibility Segregation) instead of using one shared model for both?
answer
- reads >> writes
- two models, two scaling knobs
- denormalized read views per consumer
- eventual consistency is the tax
- not always worth it at low scale
basics
~20 sBecause writing data and reading data back have different needs. CQRS keeps them as two separate models so each can be built, scaled, and hosted the way that suits it best, instead of one design compromising for both jobs.
solid answer
~40 sCQRS separates the write model — which validates commands and enforces business rules — from the read model, which is shaped purely for fast queries. In cloud systems this matters because read traffic usually dwarfs write traffic (often 10-100x), and the two have different latency, consistency, and shape requirements. Splitting them lets you scale each independently (e.g., autoscale read replicas without touching the write path), pick different storage technologies per side (a strongly-consistent write store vs. a denormalized, cache-friendly read store), and evolve query/reporting needs without destabilizing write-side domain logic. The tradeoff is operational complexity and, in most cloud deployments, eventual consistency between the two sides — a write isn't instantly visible on the read side.
go deeper
Should be able to say, in plain terms, that CQRS is about having a different model for changing data than for reading it, and give one reason (scaling, or different shapes) without needing to name specific cloud services.
Should describe the mechanism — commands go to a write model, queries go to a separately maintained read model — and name eventual consistency as the main cost.
Should discuss when the split pays off (real read/write asymmetry, multiple consumer-specific views) versus when it's overkill, and how to handle read-your-writes needs in production.
Should connect the decision to organizational and platform-level tradeoffs: which teams own which side, how the projection pipeline is operated and observed at scale, and when the pattern is being reached for out of fashion rather than need.
## The two models **Command Query Responsibility Segregation (CQRS)** is an architectural pattern that splits a system's data-handling logic into two distinct models: - a **command (write) model** that accepts requests to change state, validates them against business rules, and persists the result; - a **query (read) model** that only serves lookups, built and shaped purely for how consumers want to read data. In a single shared-model design, one schema and one set of classes have to serve both jobs — validating complex business invariants on write, and returning fast, flexible, differently-shaped views on read. That compromise gets worse as a system grows, which is why CQRS shows up so often in cloud-native architectures. ## Why split: asymmetric load The core reason to split is **asymmetric load and asymmetric requirements**. In most production systems, read traffic outnumbers write traffic by an order of magnitude or more: a social feed, a product catalog, a dashboard — all read constantly, written to occasionally. Cloud platforms bill and scale on capacity you provision, so if one model has to satisfy both a write path needing strict validation and transactional integrity, and a read path needing to serve thousands of requests per second with sub-100ms latency, you either over-provision the write store to handle read load it doesn't need, or under-serve reads. CQRS lets you scale the two independently: - the **write side** stays small and consistent; - the **read side** is replicated, cached, denormalized, or moved to a different storage technology entirely (e.g., a search index or a key-value store optimized for point lookups) and scaled out horizontally as needed — often via managed cloud services like autoscaling read replicas or serverless query layers. ## How a request flows 1. Mechanically, a request to change state (a **command**, e.g., `PlaceOrder`) goes to the write model, which validates it, applies the business logic, and persists the resulting state change. 2. Separately, one or more read models are built and kept up to date from that write side — either by directly recomputing views from the primary store, or (more commonly in cloud architectures) by consuming a stream of change events and projecting them into read-optimized stores. 3. Consumers issuing **queries** (e.g., `GetOrderHistory`) never touch the write model at all; they read from these pre-built, denormalized views, which can be tailored per use case — one view for a customer-facing order list, another for an internal fulfillment dashboard, both derived from the same underlying writes. ## Flexibility, not only speed The benefit is not just performance. It's also flexibility: because the read side is decoupled from the write side's internal schema, teams can add or reshape a read view (a new report, a new API response shape) without touching write-side domain logic or risking a migration on the transactional store. This is valuable in cloud teams working with polyglot persistence, where the write store might be a relational database or an event log, and read stores are chosen per consumer: | Read store | Consumer | |---|---| | a document database | a mobile app | | a columnar store | analytics | | a cache | a hot lookup path | ## The cost The cost is real, though. You now have two models to build, deploy, test, and reason about instead of one, and — critically in distributed cloud deployments — the read side is usually eventually consistent with the write side, because propagating a write into every read view takes some non-zero time (milliseconds to seconds, depending on the pipeline). This means a user can write data and, moments later, read a view that hasn't caught up yet — the single most common surprise teams hit when adopting CQRS in production. It also means you need observability into replication/projection lag, and a plan for what a client does when it needs to see its own write immediately. ## Where it shows up A concrete example: an e-commerce checkout writes an order through a strongly-consistent write model backed by a relational database, while the 'my orders' page, the fulfillment queue, and the analytics dashboard are all separate read views built asynchronously from the same order events, each denormalized for its own access pattern. None of those read views share a schema with the write store or with each other — that decoupling is the entire point of CQRS, and it's what makes independent scaling and independent evolution possible. Teams typically adopt CQRS only where this read/write asymmetry and independent-scaling need is real; for a low-traffic internal CRUD tool, the added complexity of two models rarely pays for itself.
- Does adopting CQRS require using two separate physical databases?No — CQRS is about separating the models/responsibilities in code, not necessarily the storage. A simple version can use the same database for both, just with different classes/queries for reads vs writes. Splitting into physically separate stores is a common but optional extension, usually adopted once the scaling or technology-choice benefits are actually needed.
- How does a client see its own write immediately if the read side is eventually consistent?Common approaches: read the just-written value directly from the write model or a synchronous read path for that one case, use a read-your-writes/session-consistency guarantee on the replica the client is pinned to, or have the client optimistically merge its own change into the UI while the projection catches up. Each adds some complexity but avoids the 'I just saved it and it's gone' user experience.
- What's the operational cost of running two models instead of one?You need to build, test, deploy, and monitor a projection/synchronization pipeline in addition to the write path; you need lag and error-rate observability on that pipeline; and you need a rebuild/backfill strategy for when a read view's shape changes or falls behind. It roughly doubles the surface area you're responsible for compared to a single shared model.
Like a newsroom: reporters (the write side) investigate a story through a careful editorial process before it's approved, while the printed paper and the website (the read side) are separate, pre-formatted products optimized for fast, easy consumption — updating one doesn't instantly change the other.
saying these in an interview costs you the question
- Says CQRS means 'always use two different databases'
- Assumes reads are always instantly consistent with the latest write
- Can't explain why read and write scaling needs differ
- Proposes CQRS for a low-traffic internal tool with no read/write asymmetry
- Doesn't mention any tradeoff or cost, only benefits