Getting Snapshots
Snapshots let you inspect how a read model reached its current state. Chronicle groups events by correlation ID, replays the read model after each group, and returns the state produced by each step.
This is useful when a projection or reducer produced a surprising result and you need to see the path as well as the final state.
How snapshots are grouped
Section titled “How snapshots are grouped”Each snapshot represents the cumulative read model state after one correlation group. In practice, a correlation group often maps to one user request, command, import batch, scheduled job, or other operation that appended related events.
Every snapshot includes:
| Field | Meaning |
|---|---|
| Read model | The read model state after that correlation group was applied |
| Events | The events that were applied for that group |
| Occurred | The timestamp of the first event in the group |
| Correlation ID | The identifier that ties the related events together |
Read snapshots
Section titled “Read snapshots”The read model type must be registered, and the key must identify the read model instance you want to inspect.
var snapshots = await eventStore.ReadModels.GetSnapshotsById<Order>(orderId);
Console.WriteLine($"Found {snapshots.Count()} snapshots.");alias MyApp.ReadModels.Order
{:ok, snapshots} = Chronicle.ReadModels.get_snapshots_by_id(Order, order_id)
IO.puts("Found #{length(snapshots)} snapshots.")const snapshots = await store.readModels.getSnapshotsById(Order, orderId);
console.log(`Found ${snapshots.length} snapshots.`);Kotlin currently exposes single-instance read-model lookup only, so snapshots are not shown for that client.
Analyze the timeline
Section titled “Analyze the timeline”Snapshot data is usually most useful when you print or inspect the correlation ID, event count, timestamp, and resulting state together.
var snapshots = await eventStore.ReadModels.GetSnapshotsById<Order>(orderId);
foreach (var snapshot in snapshots){ Console.WriteLine($"Snapshot at {snapshot.Occurred}:"); Console.WriteLine($" Correlation ID: {snapshot.CorrelationId}"); Console.WriteLine($" Event count: {snapshot.Events.Count()}"); Console.WriteLine($" State: {snapshot.Instance}");}alias MyApp.ReadModels.Order
{:ok, snapshots} = Chronicle.ReadModels.get_snapshots_by_id(Order, order_id)
Enum.each(snapshots, fn snapshot -> IO.puts("Snapshot at #{snapshot.occurred}") IO.puts(" Correlation ID: #{snapshot.correlation_id}") IO.puts(" Event count: #{length(snapshot.events)}") IO.inspect(snapshot.read_model, label: " State")end)const snapshots = await store.readModels.getSnapshotsById(Order, orderId);
for (const snapshot of snapshots) { console.log(`Snapshot at ${snapshot.occurred?.toISOString() ?? 'unknown'}`); console.log(` Correlation ID: ${snapshot.correlationId ?? 'none'}`); console.log(` Event count: ${snapshot.events.length}`); console.log(' State:', snapshot.readModel);}If you need to compare two states, materialize the snapshot list and compare neighboring entries. Chronicle gives you the timeline; your diagnostic tool decides which properties matter.
Cost and limits
Section titled “Cost and limits”Snapshot retrieval has to read the relevant history, group events by correlation ID, and replay the read model through each group. That can be expensive for keys with long histories or many correlation groups.
Use snapshots when:
- You are debugging a projection or reducer.
- You need an audit trail for how one instance evolved.
- You need to understand transaction or request boundaries.
- The key has a reasonable event history.
Prefer current-state or materialized reads when:
- You only need the latest state.
- You need to query many instances.
- You are serving a hot user-facing path.
Related topics
Section titled “Related topics”- Getting a Single Instance - Read the latest state for one key
- Getting a Collection of Instances - Replay all current instances
- Watching Read Models - Subscribe to changes as they happen