Knowledge Guide
HomeSystem DesignMicroservices Patterns

The Problem Traditional CRUD Operations

A single CRUD model forces reads and writes to share one schema, one index set, one lock domain, and one storage engine, so every knob you turn to speed one path structurally slows the other — that coupling, not raw load, is why the two cannot be scaled independently.

Why one model actually blocks independent scaling

"Reads and writes are different" is true but shallow. The real problem is physical coupling. In a traditional CRUD design, a balance inquiry and a deposit both hit the same rows in the same table:

So you can scale the machine (bigger box, more replicas), but you cannot scale the two workloads apart, because they are literally the same physical object with one set of tuning parameters.

diagram
diagram

Worked trace: a banking ledger under load

Concrete numbers make the coupling visible. Suppose a transactions table holds every posting: 1,000,000 accounts × ~5,000 postings each ≈ 5 billion rows. Balance is derived, not stored:

SELECT SUM(amount) FROM transactions WHERE account_id = ?;

Live load: 12,000 balance inquiries/sec (mobile app auto-refresh) and 400 postings/sec (writes). Each inquiry aggregates ~5,000 rows, so the read path grinds through ~60 million rows/sec while the write path inserts only 400. Watch what happens to every attempted fix — each one speeds one path only by taxing the other, because both live in the same model:

Change you makeEffect on READSEffect on WRITESWhy it stays coupled
Index on (account_id)Locates the 5,000 rows fast, but still aggregates all of them per queryEvery INSERT must maintain the index — extra WAL + write amplificationOne table, one index set — the write pays for the read's index
Covering index (account_id, amount)Index-only scan, but still 5,000 entries summedLarger index, more amplification per postingFaster read is literally funded by slower write
Materialized balance column on accountsO(1) single-row lookup — huge winEvery posting now UPDATEs the same account row → row-lock contention; concurrent deposits serialize; MVCC version churnRead and write now fight over the exact same row
Add read replicasSpreads 12k qps across nodes — but each replica re-runs the same 5,000-row SUM; per-query latency unchangedPrimary ships every write to every replica; readers see stale balances (replication lag)Replicas copy the write schema, so they copy its query cost

No row in that table decouples the workloads. Each buys read speed with write pain (or the reverse) because there is one schema, one index set, one lock domain. The only way to scale the paths independently is to stop sharing the model: keep an append-only, write-optimized ledger and a separate, read-optimized store of precomputed balances, synced asynchronously. Splitting the model that way is CQRS — this problem is exactly the pressure that motivates it.

Pitfalls

When the single CRUD model is fine — and when to leave it

Single-model CRUD is a legitimate default, not a mistake. The engineering judgment is knowing which rung of the ladder your problem is actually on. There is a spectrum between "one model" and full CQRS; jump only as far as the pressure requires.

Keep one CRUD model when

The ladder of cheaper alternatives (try these before CQRS)

Move to CQRS (separate read and write models) when

What CQRS costs: two models to keep in sync, an async projection pipeline, eventual consistency on the read side, more moving infrastructure, and harder debugging. Choose the single model when a replica or cache closes the gap; prefer CQRS when read and write must evolve, scale, and be tuned as separate systems — and only then.

Takeaways


Re-authored/Deepened for this guide. Sources: Microsoft Azure Architecture Center, "CQRS pattern" and "Command and Query Responsibility Segregation"; Martin Fowler, "CQRS" and "ReportingDatabase"; Greg Young, "CQRS Documents"; Vaughn Vernon, Implementing Domain-Driven Design; Martin Kleppmann, Designing Data-Intensive Applications (derived data, materialized views, and the read/write coupling of a single storage engine).

🤖 Don't fully get this? Learn it with Claude

Stuck on The Problem Traditional CRUD Operations? Open Claude, copy a block below, and it'll teach you this exact concept — visually and interactively.

🎨 Explain it visually

Build the mental picture, not memorization.

I just read a lesson on **The Problem Traditional CRUD Operations** (System Design) and want to truly understand it. Explain The Problem Traditional CRUD Operations from first principles using ONE vivid real-world analogy and a visual mental model — draw it as ASCII art or a clear step-by-step diagram — with a concrete example using real numbers. Then ask me one question to check I got the mental picture, and wait for my reply. If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.
🤔 Walk me through it (interactive)

Socratic — adapts to where you're stuck.

Teach me **The Problem Traditional CRUD Operations** interactively. Ask me ONE guiding question at a time, wait for my answer, and adapt to my confusion — build the idea with me step by step instead of explaining it all at once. If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.
🧪 Quiz me & fix my gaps

Active recall exposes what you missed.

Quiz me on **The Problem Traditional CRUD Operations** with 5 questions, easy to tricky, ONE at a time. Tell me if each answer is right; at the end, explain clearly what I got wrong and why. If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.
🧠 Make it stick

Intuition + hook + flashcards for long-term memory.

Help me remember **The Problem Traditional CRUD Operations** for the long term: give the one-sentence intuition, a memorable hook/mnemonic, a tiny worked example, and 3 active-recall flashcards (Q -> A). If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.

📝 My notes