Cards/ArchitectureSystem Design · Day 95Nov 5, 2026

Reads And Writes Want Different Things

A normalised write model and a flat read model pulling a single schema in opposite directions, then CQRS splitting them into a command side that emits events and a query side building a search index, reporting table and cached summary

One model serves both sides of a system, and the two sides want different things from it. Writes want it normalised — no duplication, every rule in one place, validation that holds. Reads want it flat: pre-joined, shaped like the screen, no joins at runtime.

So we compromise. Denormalised fields creep in for the reads, expensive joins stay for the writes, and both sides end up with something slightly wrong.

CQRS splits the model in two. The command side stays normalised and validated, and emits events describing what happened. The query side consumes that stream and builds whatever views it needs — a search index, a reporting table, a cached summary — each shaped for one job.

What it costs is immediacy. Read models lag the writes, so a user who just saved something may not see it yet, and every one of those views is another thing to operate, monitor and rebuild.

Which is why the trigger matters: clearly different read and write needs, or several views over the same data. For ordinary CRUD it is complexity bought for nothing.

One model that serves two purposes usually serves neither — but splitting it is a cost we should be forced into, not drawn to.

One model that serves two purposes usually serves neither — but splitting it is a cost we should be forced into, not drawn to.