skip to content

CQRS separates the model used to handle commands (writes) from the model used to handle queries (reads). Is Event Sourcing a required part of implementing CQRS, or is it a separate, optional choice? Explain how the two typically fit together when a team does use both.

level: juniorimportance: must knowfreq 70%

answer

  1. orthogonal patterns
  2. ES = write persistence, CQRS = model split
  3. event log solves ES's query weakness via projections
  4. CQRS alone doesn't require an event log

basics

~20 s

CQRS just means writes and reads use different models. Event Sourcing means you store every change as an event instead of overwriting data. You can do CQRS without Event Sourcing, but when a team does use Event Sourcing, the event log naturally becomes the write side and the read side is built from those events.

solid answer

~50 s

CQRS and Event Sourcing are orthogonal patterns that happen to complement each other extremely well. CQRS just says: use a different model (and often different storage) for accepting commands than for serving queries; it says nothing about how the write model persists state — it could be a normal table updated in place. Event Sourcing says: persist state as an append-only sequence of events rather than mutable rows. When you combine them, ES supplies the write-side persistence (the event log is the 'database' for commands) and CQRS supplies the mechanism for turning that log into fast, query-optimized read models via projections. You can have CQRS without ES (state-stored write model, separate read replica), and ES without CQRS is technically possible but rare, since querying an event-sourced aggregate for anything beyond 'get by ID' is awkward without a projected model.

go deeper

for a junior

Should know the one-line distinction: CQRS splits models, ES changes how state is stored. Doesn't need to explain projections in depth.

for a middle

Should be able to explain why the two commonly appear together and name the event log as the write-side source of truth.

for a senior

Should articulate the trade-offs of pairing them (audit trail, retroactive read models vs. eventual consistency, operational overhead) and know when to reach for CQRS alone.

for a principal

Should be able to advise a team on whether to adopt the pairing at all for a given domain, weighing long-term schema evolution and organizational readiness for eventual consistency against the audit/replay benefits.

## Two patterns, one common confusion CQRS (Command Query Responsibility Segregation) and Event Sourcing (ES) are two separate architectural patterns that solve different problems, and it's easy to conflate them because they show up together so often in the same tutorials and production systems. - **CQRS** is about splitting the model that handles writes (commands) from the model that handles reads (queries). Instead of one class or one table serving both 'change the order' and 'show me the order list,' you build two models: a command model optimized for validating business rules and applying changes, and one or more query models optimized for however the UI or downstream consumer wants to read the data — denormalized, joined, pre-aggregated, whatever shape is fastest to serve. - **Event Sourcing**, by contrast, is a persistence strategy: instead of storing the current state of an entity as a row you overwrite in place, you store the full sequence of state-changing events that happened to it (`OrderPlaced`, `OrderShipped`, `OrderCancelled`) as an append-only log, and current state is derived by replaying those events. ## Either one stands alone Neither pattern requires the other. - You can build a perfectly good CQRS system where the command side just writes to a normalized relational table and publishes a domain event afterward for integration purposes — no event log, no replay, just a write model and a separately maintained read replica or materialized view. - Conversely, you could theoretically apply Event Sourcing to a system that still exposes one unified read/write model, though this is unusual in practice because querying an event-sourced aggregate for anything beyond 'get by ID' is awkward — you'd have to replay events to answer even simple list or filter queries, which is slow and doesn't scale. ## Why they are so often paired The reason the two are so often paired is that each one solves the other's weak spot. - **Event Sourcing's biggest practical problem is querying.** An append-only log of events is a fantastic write model (it captures full history, gives you an audit trail for free, and never loses information through in-place overwrites) but a terrible query model, because answering 'show me all overdue orders' means scanning and replaying potentially every event for every order. - **CQRS's biggest practical problem, when adopted alone**, is that it still needs some answer for how the write side persists state, and teams often reach for the same normalized schema they'd use in a CRUD app, which under-uses the pattern. Put together, Event Sourcing supplies the write-side persistence mechanism (the event log is the durable store for commands, and aggregates are reconstituted by replaying their own events), and CQRS supplies the mechanism for turning that log into however many purpose-built, denormalized read models the application needs, each kept up to date by a **projector** that subscribes to the event stream. The event log becomes the single source of truth; every read model is a derived, disposable view. ## The trade-off of pairing them The trade-off of pairing them is real, not free. On the plus side: - you get a full audit log with no extra engineering; - you can add new read models retroactively over historical data because the events are still there; - the write and read sides scale independently. On the cost side, the system becomes **eventually consistent by construction** — the read models lag the event log by however long the projector takes to catch up — and the team takes on real operational machinery: - an event store; - a projection/subscription mechanism; - schema evolution for events over years of production use; - a mental model shift for every engineer touching the write side, since 'update this field' is no longer a valid operation; you can only append a new event describing what happened. ## Three read models over one order stream A concrete example: an order-management system might have a single `Order` aggregate stream per order (events like `OrderPlaced`, `ItemAdded`, `PaymentAuthorized`, `OrderShipped`), while the read side maintains three independent projections built from that same stream: 1. a 'customer order history' table for the customer-facing UI; 2. a 'warehouse picking queue' table for fulfillment staff; 3. a 'revenue by day' rollup for finance dashboards. None of those three read models share a schema, none of them are ever updated in place from a UI action, and all three can be rebuilt from scratch by replaying the `Order` events if their projection logic changes — a capability a plain CRUD table with CQRS bolted on top doesn't give you for free.

  • If you have CQRS without Event Sourcing, how does the read model normally get its data?
    Typically the command model writes to its own normalized store, and either publishes an integration event after each successful write or the read model is refreshed by a change-data-capture (CDC) process reading the write database's transaction log. There's no per-aggregate event history here — just a signal that 'something changed, go re-fetch or re-derive.' The read model reflects the latest state, not the sequence of changes that produced it.
  • Why is it rare to see Event Sourcing used without CQRS in production?
    Without a separate query model, every read has to go through the same aggregate-reconstitution path as a write — replay events, build state, then filter or search in memory — which is fine for 'get by ID' but breaks down for anything list-like or reporting-like. In practice teams almost always add at least one projected read model as soon as they need a second kind of query, which is CQRS by definition, even if they didn't set out to build it.

Think of CQRS as deciding to have a separate cash register (writes) and a separate financial report (reads) instead of one ledger book serving both purposes. Event Sourcing is a decision about how the cash register itself keeps records — as a receipt tape of every transaction rather than a single running balance you erase and rewrite. You can have a receipt tape without splitting register from report, and you can split register from report while the register still just keeps a balance — but a receipt-tape register pairs beautifully with a separate report, because the report is built by summing the tape.

saying these in an interview costs you the question

  • Says Event Sourcing 'is' CQRS or that you can't have one without the other
  • Can't explain what problem each pattern solves independently
  • Assumes the read model is just 'a copy of the database,' not something derived by replaying/projecting events
  • Believes CQRS requires two separate databases as a hard rule

context