---
title: "Instrument catalog: Snapshot cursors (sourced from SnapshotLeafGrain / snapshot-cursor open path) - Metrics"
url: "https://nsta1.github.io/Orleans.Lattice/docs/lattice/metrics/instrument-catalog-3.html"
source: "https://github.com/NSTA1/Orleans.Lattice/blob/release/9.9/docs/lattice/metrics.md?plain=1#L296-L303"
package: "Orleans.Lattice"
version: "9.9.0"
documents: "Orleans.Lattice 9.9.0 (release line 9.9)"
built: "2026-10-04"
all-pages: "https://nsta1.github.io/Orleans.Lattice/llms.txt"
bundle: "https://nsta1.github.io/Orleans.Lattice/docs/lattice/llms-full.txt"
---
# Instrument catalog: Snapshot cursors (sourced from `SnapshotLeafGrain` / snapshot-cursor open path)

Part of [Instrument catalog](instrument-catalog.md), in [Metrics](../metrics.md).

## Snapshot cursors (sourced from `SnapshotLeafGrain` / snapshot-cursor open path)

| Name | Kind | Unit | Description |
|---|---|---|---|
| `orleans.lattice.snapshot.replay.duration` | `Histogram<double>` | `ms` | Per-shard WAL-replay duration observed during a zero-observable-writes snapshot-leaf open. Emitted by `SnapshotLeafGrain` after a successful replay over `[0, capturedOffset)`. Tagged `tree` and `shard`. |
| `orleans.lattice.snapshot.replay.entries` | `Counter<long>` | `{entry}` | WAL entries consumed by the snapshot-leaf replay engine; one increment per `CommitLogSliceEntry` processed (including filtered / skipped records, because they contribute to wall-clock replay cost). Tagged `tree` and `shard`. |
| `orleans.lattice.snapshot.pins` | `ObservableGauge<long>` | `{pin}` | Snapshot cursors registered as consumers in the WAL cursor registry for the tree, derived at observation time from the registry's live set of snapshot consumer ids. Tagged `tree` and `tenant`. **These registrations do not hold back WAL trimming today**: a snapshot cursor registers with a cursor of `HybridLogicalClock.Zero` and no blocked floor or version vector, because its anchor HLC is always zero, and the cursor registry leaves a zero cursor out of the minimum the WAL GC reads, while a missing floor or vector constrains nothing. The snapshot does not need them to: its pages are served from per-shard baselines frozen when it opened, and only a coordinate persisted before that baseline store existed replays the WAL instead. Read the gauge as a count of open snapshot cursors, not of retained WAL. **Zero-primed**: the WAL GC scheduler registers each tree on its first pass, so a tree that has never opened a snapshot cursor reports an explicit `0`. Without that priming a tree with no snapshot cursors exported no series, which is indistinguishable from a tree whose pin accounting is broken (issue #2694). Because the gauge reports the pins held *now* rather than accumulating `+1` / `-1`, an activation lost while holding a pin leaves no residue: the pin is still reported for as long as the registry holds it, and the series falls to zero when it does not, with no compensating write to lose (issue #2700). A value that climbs and never comes back down is therefore a real registration leak rather than accumulated drift. **Staleness bound**: the value is the pin set as of that tree's last WAL GC pass, not as of the scrape, so a pin lost with its silo clears within that tree's effective GC interval (`WalGcMinInterval` to `WalGcInterval`, 30 s to 1 h by default; a quiet tree sits near the ceiling, a blocked one at the floor). Setting `WalGcInterval` to zero or less disables the scheduler, which leaves both the priming and the self-healing re-derivation inert. |

Previous: [Instrument catalog: Leaf-level (sourced from BPlusLeafGrain)](instrument-catalog-2.md). Next: [Instrument catalog: WAL garbage collector (sourced from LatticeWalGc)](instrument-catalog-4.md). Contents: [Metrics](../metrics.md).
