I don't think you necessarily have to have all this in a useful CQRS system.
E.g., here's a real-world example of a general pattern in which CQRS is pretty simple and useful:
A walking/running app which tracks distance, time, and other relevant information over the course of a workout.
It collects a series of events like "location changed at time X", "user started workout", "user paused workout" etc., over the course of the workout period (actually starting before the user officially starts the workout), and converts these to time, distance and other stats.
This fits CQRS really well since the input is inherently a series of events and the output is information gleaned from processing those events.
You get a full CQRS system by simply fully logging the events.
The advantage is that you can go back and reprocess the sequence if you want to glean new/different information from the sequence. E.g., in the walking/running app you could, after the fact and at the user's discretion, detect and fix the case where the user forgets to start or stop a workout. Or recalc distance in the case where you detect a bug or misapplication of your smoothing algorithm, etc. Or draw a pace graph or whatever.
In all these cases you can process the events synchronously.
I put this all in terms of a workout app, but there is a general pattern of an event-driven session-based activity or process, where you may want/need to derive new information from the events and the cost is to log the events (in a high-fidelity form so they could be fully reproduced.
Whether or not you need to use queues and distributed data stores is an independent decision.
That's not "Command Query Responsibility Segregation" (CQRS). That's modeling your data as a time series - which is a totally valid and perfectly useful model in many cases, but has nothing to do with the architectural pattern known as CQRS.
Martin Fowler gives the following simple definition of CQRS:
> At its heart is the notion that you can use a different model to update information than the model you use to read information.
CQRS takes data (events, time series, plain old records, whatever), stores it into a write store which acts as a singular source of truth, and queues that data to be stored in a (usually eventually consistent) read store as a projection - not simply duplicating the write store, but building a read record meant to be consumed directly by some client - with potentially several projections, one for each set of client needs.
But what is the distinction between what Fowler describes and what I describe? There's not really a contradiction with what you describe either.
I have a distinct write store and read store, with very different models. As you say, the write store is the source of truth. Since the read store is updated synchronously with the write store there's no need for a queue between them. Indeed there are also multiple projections for different client needs (e.g. the pace chart, vs. workout progress), though in this case I don't generally need them until after the sequence of events is complete, which simplifies things.
Maybe we're just have a pointless debate on semantics, in which case, never mind.
It's just that I see this as a quite valuable pattern without necessarily bringing distributed stores into it. Indeed, part of its value is that you can start simple and later extend it to a scaling distributed system without disrupting the whole pattern.
You're right. Nothing about CQRS demands any kind of asynchronization or distributed system. It is quite simply a system where you have different models for updating and querying the system. You don't even need to have an event store for it to be a CQRS system, but it makes so much sense that I have a hard time imaging using CQRS without and ES of some kind.
E.g., here's a real-world example of a general pattern in which CQRS is pretty simple and useful:
A walking/running app which tracks distance, time, and other relevant information over the course of a workout.
It collects a series of events like "location changed at time X", "user started workout", "user paused workout" etc., over the course of the workout period (actually starting before the user officially starts the workout), and converts these to time, distance and other stats.
This fits CQRS really well since the input is inherently a series of events and the output is information gleaned from processing those events.
You get a full CQRS system by simply fully logging the events.
The advantage is that you can go back and reprocess the sequence if you want to glean new/different information from the sequence. E.g., in the walking/running app you could, after the fact and at the user's discretion, detect and fix the case where the user forgets to start or stop a workout. Or recalc distance in the case where you detect a bug or misapplication of your smoothing algorithm, etc. Or draw a pace graph or whatever.
In all these cases you can process the events synchronously.
I put this all in terms of a workout app, but there is a general pattern of an event-driven session-based activity or process, where you may want/need to derive new information from the events and the cost is to log the events (in a high-fidelity form so they could be fully reproduced.
Whether or not you need to use queues and distributed data stores is an independent decision.