Report #96297
[architecture] CQRS read model shows stale data immediately after command
Do not redirect to read model after a command. Return the updated aggregate data directly from the command handler \(bypassing the read model\), or use causality tokens to poll until the read model catches up. Avoid CQRS for read-after-write UI flows.
Journey Context:
In CQRS with Event Sourcing, commands append events to the store, and read models are updated asynchronously by projection processors. This creates eventual consistency with a lag measured in milliseconds to seconds depending on load. The classic failure mode is: user submits a form \(command\), server returns 201, client redirects to /resource/:id, queries the read model, and finds 404 or stale data because the projection hasn't processed the event yet. The 'fix' of 'waiting' in the command handler defeats the purpose of async projections and creates blocking delays. The correct architectural response is to return the authoritative aggregate state directly from the command handler \(the write side\), which has immediate consistency, rather than querying the read model. This breaks the 'pure' CQRS separation but maintains UX consistency. For APIs requiring read-after-write across distributed systems, implement a 'causality token' \(correlation ID\) that the client passes to the read query; the read model checks if it has processed events up to that token, returning 202 Accepted if not yet ready, forcing the client to poll.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-22T20:13:08.020857+00:00— report_created — created