Getting a Single Instance
When you need one read model and correctness matters more than query latency, read it by key from the event store. Chronicle rebuilds the instance from the events that feed that read model, so the result reflects the events that have been appended up to that call.
Use this path for command-side decisions, read-after-write flows, and diagnostic tools. Use materialized read models when the same data is read frequently by lists, dashboards, or user interfaces that need paging.
How it works
Section titled “How it works”When you ask Chronicle for one read model instance, the client sends the read model type and key to the kernel. Chronicle resolves the projection or reducer that owns that read model, replays the relevant events, applies compliance release rules when needed, and returns the current shape for that key.
This makes the read strongly consistent. The cost is replay: longer histories take longer to rebuild than a materialized lookup.
Read by key
Section titled “Read by key”The read model type must already be registered by the client, either as a model-bound projection, a declarative projection, or the read model produced by a reducer.
AccountInfo? account = await eventStore.ReadModels.GetInstanceById<AccountInfo>(accountId);
if (account is not null){ Console.WriteLine($"{account.Name}: {account.Balance:C}");}val account = store.readModels.getInstanceByKey(AccountInfo::class, accountId)
if (account != null) { println("${account.name}: ${account.balance}")}import io.cratis.chronicle.IEventStore;import io.cratis.chronicle.readModels.ReadModel;import kotlin.jvm.JvmClassMappingKt;import kotlinx.coroutines.BuildersKt;import kotlin.coroutines.EmptyCoroutineContext;import kotlin.coroutines.Continuation;
@ReadModelrecord AccountInfo(String name, double balance) { AccountInfo() { this("", 0.0); }}
class ReadModelLookup { void printAccount(IEventStore store, String accountId) throws InterruptedException { var account = (AccountInfo) BuildersKt.runBlocking( EmptyCoroutineContext.INSTANCE, (scope, continuation) -> { @SuppressWarnings("unchecked") var readContinuation = (Continuation<? super AccountInfo>) continuation; return store.getReadModels().getInstanceByKey( JvmClassMappingKt.getKotlinClass(AccountInfo.class), accountId, readContinuation); });
if (account != null) { System.out.println(account.name() + ": " + account.balance()); } }}alias MyApp.ReadModels.AccountInfo
{:ok, account} = Chronicle.ReadModels.get_instance_by_id(AccountInfo, account_id)
if account do IO.puts("#{account.name}: #{account.balance}")endconst account = await store.readModels.getInstanceById(AccountInfo, accountId);
console.log(`${account.name}: ${account.balance}`);Each client names the operation in its own idiom, but the inputs are the same: the read model type and the read model key.
Missing instances
Section titled “Missing instances”If no events have produced that read model key, clients return their normal “not found” shape: null, nil, or an empty result depending on the language. Treat that as “no state exists yet,” not as a projection failure.
If the read model type itself is unknown, that is a configuration error. Register the projection, reducer, or read model before querying it.
When to use this
Section titled “When to use this”Use a single-instance replay when:
- A command needs the exact current state before making a decision.
- You append an event and immediately need to read the state it creates.
- A debugging or audit tool needs deterministic state from the event log.
- The event history for that key is short enough that replay cost is acceptable.
Prefer a materialized read model when:
- The same data is read often.
- The history for each key can grow large.
- You need paging, sorting, or database-native filtering.
- Eventual consistency is acceptable.
Related topics
Section titled “Related topics”- Getting a Collection of Instances - Replay all instances for reporting or analysis
- Getting Snapshots - Inspect how one instance evolved over time
- Watching Read Models - React to read model changes as they happen
- Materialized Read Models - Page through sink-stored read models