Tag conventions
This page is part of the documentation for Orleans.Lattice 9.9.0 (release line 9.9), built 2026-10-04. It is also published as markdown, with every table and list, at tag-conventions.md, and llms.txt lists every page.Part of Metrics.
Every Lattice instrument draws its tags from one consistent, low-cardinality vocabulary. The table lists every tag key the catalog below uses; where a key is shared by many instruments, Applies to names examples and each instrument's row lists its own arms:
| Tag key | Applies to | Value |
|---|---|---|
tree |
every tree-scoped instrument - a platform-scoped instrument (for example the registry instruments, the WAL replay permit gauges, or orleans.lattice.build.info) carries none; see each instrument below |
The logical tree id - the id the tree's ILattice grain is addressed by - which grain-side series keep across an alias swap; the WAL garbage collector, the WAL storage providers and a few named series carry the physical copy's id instead: see The tree dimension across aliasing |
tenant |
every instrument | Owning tenant derived from the tree id rather than measured: a tenant id, default for a bare legacy tree id, or the reserved _platform_ sentinel for the _lattice_ and sys- namespaces, for a malformed id in the reserved t/ namespace, and for an instrument or arm with no tree dimension. Most descriptions below leave it out of their tag list, but every series carries it, and a hygiene gate over every emission site keeps it that way. See The derived tenant label |
shard |
instruments whose row lists a shard tag, on the shard-root side (for example orleans.lattice.shard.reads and the orleans.lattice.shard_root.scan_page.* family) and on the WAL side (the WAL append pipeline, WAL GC trim, WAL compaction and recovery, and storage-provider commit instruments) |
An int index with two meanings that are never joined: the tree's physical shard on the shard-root side, and the WAL shard - a mutation's partition, 0 to WalPartitions - 1 - on the WAL side. Distinct from partition and pin_shard below |
operation |
orleans.lattice.leaf.scan.duration, orleans.lattice.registry.call.duration, orleans.lattice.registry.call.in_flight, orleans.lattice.shard_root.set_many.local_apply.duration, orleans.lattice.shard_root.set_many.leaf_rpc.duration |
keys or entries (leaf.scan.duration); the registry member served - exists, get_entry, get_entries, resolve, get_shard_map, get_all_tree_ids, register, or unregister - on the two registry instruments; set_many (unconditional SetManyAsync) or set_many_where_predicate (conditional SetManyWherePredicateAsync) on the two shard-root batched-write instruments |
step |
orleans.lattice.leaf.commit.duration only |
wal, apply, observer, or digest |
observer |
orleans.lattice.observer.duration only |
The IMutationObserver implementation's CLR type name (Type.FullName) |
stage |
orleans.lattice.set.stage.duration, orleans.lattice.set_many.stage.duration, orleans.lattice.get.stage.duration, orleans.lattice.get_many.stage.duration, orleans.lattice.saga.broadcast.shard.stage.duration, orleans.lattice.wal.gc.pass.reach, orleans.lattice.wal.gc.tree.reach |
Sub-stage name within an envelope, or the region a WAL GC pass reached (the two reach instruments) - see each instrument below |
phase |
the storage-provider commit instruments (orleans.lattice.provider.commit.duration, orleans.lattice.provider.retry.exhausted, orleans.lattice.provider.idempotent_replays, orleans.lattice.provider.phase1.transient_retries); the scan-page stall instruments (orleans.lattice.shard_root.scan_page.stalls, orleans.lattice.scan.stall_resumptions, orleans.lattice.scan.stall_futility_outcomes); orleans.lattice.saga.checkpoint.duration, orleans.lattice.saga.reminder.duration, orleans.lattice.atomic_action.step, orleans.lattice.wal.gc.scheduler.phase_age |
phase1 (per-batch partition txn) or phase2 (manifest partition txn) on the provider instruments, where idempotent_replays and phase1.transient_retries are always phase1; prologue, descent, leaf-walk or baseline-fold on the scan-page instruments; the call site on the two saga instruments; forward or compensate on atomic_action.step; the scheduler loop's phase on phase_age |
status |
orleans.lattice.provider.retry.attempts, orleans.lattice.provider.retry.exhausted, orleans.lattice.provider.retry.short_circuited; the WAL GC pin-classification and floor instruments (orleans.lattice.wal.gc.blocking_pin_state, orleans.lattice.wal.gc.orphan_pin_sweep, orleans.lattice.wal.gc.floor_holder_classification, orleans.lattice.wal.gc.coverage_unknown_pin_offset, orleans.lattice.wal.gc.never_checkpointed_pin_offset, orleans.lattice.wal.gc.floor_holder_admission, orleans.lattice.wal.gc.floor_holder_offset_admission, orleans.lattice.wal.gc.durable_floor_stall_seconds) |
Azure Tables HTTP status string on the provider instruments (e.g. 503, 429; 0 for a transport-level failure with no HTTP exchange; unknown when the SDK surfaced no status); a classification arm on the WAL GC instruments - see each instrument below |
outcome |
many instruments - every row below that lists outcome arms, for example orleans.lattice.atomic_write.completed, orleans.lattice.wal.gc.passes, orleans.lattice.leaf.snapshot.captures and orleans.lattice.grain.call.duration |
Discriminator - see each instrument below |
kind |
orleans.lattice.coordinator.completed, orleans.lattice.coordinator.phase_tick.failures, orleans.lattice.coordinator.phase_tick.consecutive_failures, orleans.lattice.tree.lifecycle, orleans.lattice.events.published, orleans.lattice.leaf.write.duration, orleans.lattice.leaf.residency.sheds, orleans.lattice.shard_root.flush.retries_suspended, orleans.lattice.compress.dictionary.reservoir_fill |
Discriminator - see each instrument below |
trigger |
orleans.lattice.compaction.pass.duration, orleans.lattice.compaction.leaves.visited, orleans.lattice.leaf.compaction.duration, orleans.lattice.leaf.tombstones.reaped, orleans.lattice.leaf.tombstones.expired, orleans.lattice.wal.compactions, orleans.lattice.wal.replay.permit_adaptations |
reminder, ratio, size, or operator (the five tombstone-compaction instruments - always on compaction.pass.duration, and on the other four only when a compaction policy knob is non-default); ratio, ceiling, or reconcile (wal.compactions); fault or occupancy (permit_adaptations, withheld arm only) |
path |
orleans.lattice.compaction.leaves.visited, orleans.lattice.leaf.digest.publishes |
walk or dirty-set (compaction.leaves.visited); coalesced_scheduled, coalesced_skipped, coalesced_fired, inline, or deactivation_flush (leaf.digest.publishes) |
reason |
many instruments - every row below that lists reason arms, for example orleans.lattice.events.dropped, orleans.lattice.leaf.activation.failures, orleans.lattice.wal.gc.trim_stop and orleans.lattice.storage.wal.compression_skipped |
Discriminator - see each instrument below |
config |
orleans.lattice.config.changed |
Configuration dimension name: publish_events or history_retention |
wal_partitions |
the WAL append-pipeline histograms (orleans.lattice.wal.append.*, orleans.lattice.wal.shard.dispatch.*) and the saga coordinator's histograms (orleans.lattice.saga.prepare.duration, orleans.lattice.saga.terminal_decision.duration, orleans.lattice.saga.broadcast.duration, orleans.lattice.saga.checkpoint.duration, orleans.lattice.saga.reminder.duration, orleans.lattice.saga.fanout.size, orleans.lattice.saga.perkey.duration) - not the WAL GC, compaction or replay histograms |
LatticeOptions.WalPartitions at the time of activation (Phase A attribution) |
wal_max_pending_batches |
the WAL append-pipeline histograms (orleans.lattice.wal.append.*, orleans.lattice.wal.shard.dispatch.*) |
LatticeOptions.WalMaxPendingBatches at the time of activation (Phase A attribution) |
pipeline_phase2 |
orleans.lattice.provider.commit.duration |
true or false, reflecting AzureTableWalStorageOptions.PipelinePhaseTwoCommits |
shard_count |
orleans.lattice.warmup.duration |
Per-tree physical-shard-root probe fan-out |
grain_type |
orleans.lattice.grain.call.outstanding_depth, orleans.lattice.grain.call.duration |
Target Orleans grain type name (e.g. bplusleaf) |
method |
orleans.lattice.registry.caller.duration only |
ILatticeRegistry member name as declared (e.g. ResolveAsync, UpdateAsync) - the same name Orleans prints in a timeout line; other for a name not on the interface |
partition |
the leaf replay instruments (orleans.lattice.leaf.activation_replays_over_budget, orleans.lattice.leaf.activation_stalled_replays, orleans.lattice.leaf.deferred_terminals_dropped_at_cap, orleans.lattice.leaf.unresolved_prepare_ledger_beyond_cap, orleans.lattice.wal.replay.slice_narrowings), orleans.lattice.wal.gc.blocking_pin_state, orleans.lattice.wal.gc.coverage_unknown_pin_offset, orleans.lattice.wal.gc.never_checkpointed_pin_offset, every orleans.lattice.wal.writer.* instrument, and the partition location tag on orleans.lattice.wal.saturation.transitions |
WAL partition ordinal, bounded by WalPartitions (plus the reserved value none on the blocking_pin_state reachability priming, and unknown on a WAL GC pin classification whose consumer id names no partition). Kept apart from shard so a future fan-out that decouples the writer partition from the destination WAL shard cannot overload shard |
pin_shard |
orleans.lattice.materialiser.pin.reports_shed, orleans.lattice.materialiser.pin.shed_forced, orleans.lattice.materialiser.pin.shed_stall_seconds |
Durable leaf-materialiser pin shard: a hash of the consumer id modulo WalMaterialiserPinShards. Never join it to shard - both default to eight values, so the join looks well-formed and means nothing |
dimension |
orleans.lattice.admission.rejected, orleans.lattice.admission.would_reject, orleans.lattice.admission.utilization |
keys or bytes |
decision |
orleans.lattice.shard.healing.decisions |
The over-split healing sweep's decision - see that instrument |
state |
orleans.lattice.wal.saturation.transitions, orleans.lattice.view.source_backpressure |
Saturation regime, lowercased: the new state (healthy, throttled or saturated) on transitions; the observed source regime (throttled or saturated) on source_backpressure |
previous_state |
orleans.lattice.wal.saturation.transitions |
The regime the tree left, spelt as state |
cause |
orleans.lattice.wal.saturation.transitions, orleans.lattice.wal.gc.scheduler_backoff, orleans.lattice.wal.gc.scheduler_consecutive_faults, orleans.lattice.wal.gc.orphan_pin_sweep (removal-decision arms only), orleans.lattice.wal.gc.drive_orphan_pin_retirement |
The sampler input a saturation transition was attributed to (transitions); scheduled, faulted or empty (the two scheduler instruments); the evidence a WAL GC pin-removal decision rested on - orphaned, no_durable_state or not_driven (the two orphan-pin instruments, issue #4246) |
view |
every orleans.lattice.view.* instrument |
Materialised-view name |
index |
every orleans.lattice.tag_index.reconcile.* instrument |
Tag-index name |
activation_temperature |
orleans.lattice.leaf.activation_replays, orleans.lattice.leaf.activation.failures, orleans.lattice.leaf.deactivation.checkpoint_delta |
cold or warm |
deactivation_reason |
orleans.lattice.leaf.deactivation.checkpoint_delta |
The Orleans DeactivationReasonCode name |
detach_seam |
orleans.lattice.leaf.bisect_refusals |
The cache surface that released a leaf's snapshot frame - see that instrument |
failure_class |
orleans.lattice.leaf.split_attempts (faulted arm only) |
unaffordable, timeout or other |
origin |
orleans.lattice.leaf.span_fail_open_commits |
client_write, merge or cross_shard_migration |
arm |
orleans.lattice.saturation.refusals, replay_permit_admission source only |
Which arm of the replay admission predicate refused (issue #3921): wait_exceeded (the smoothed wait of recently terminated permit waits reached WalReplayPermitMaxQueueWait), no_progress (no permit was released to the queue for WalReplayPermitMaxQueueWait) or gc_share (a background starvation drive - a WAL GC sweep's, or a leaf's own coverage-lag timer's - found the GC share of permits full or no permit immediately free) |
source |
orleans.lattice.saturation.refusals only |
The admission seam that refused, as the snake_case form of the LatticeSaturationSource it carries: unspecified, wal_admission, atomic_write_saga, snapshot_cursor_open, replay_permit_admission, set_many_fan_out, set_many_envelope or tx_registry_capacity |
tree_count |
orleans.lattice.atomic_write.cross_tree.completed |
Number of participating trees |
version, sha |
orleans.lattice.build.info only |
Package version and full 40-character commit sha the process was built from |
Leaf grain ids are not emitted as a tag - in a large tree they would produce unbounded tag cardinality. All leaf instruments are aggregated to the tree level.
The tree dimension across aliasing
A resize, a shadow-cutover restore (and its revert) and a schema remediation
move a tree's data onto a new physical copy behind a registry
alias. The tree tag does not follow the
physical copy: every grain that serves a physical copy created to back a logical
tree tags its series with that logical tree's id, read once from the copy's
DerivedFrom provenance when the grain
activates. A dashboard or alert filtered on tree therefore keeps those series
through any number of resizes, restores and remediations, with no gap and no
second series under the physical id - except the series listed under Series
under the physical id below.
- Retired copies. Maintenance that still runs on a retired or discarded copy
keeps the logical owner's
treevalue it resolved at activation, so it is attributed to the tree the copy belonged to. - Independent trees. A tree registered without provenance - an ordinary tree, a standalone snapshot destination, or an entry written before provenance existed - keeps its own id. An administrative alias does not rewrite that identity: the series of a tree aliased onto an independent tree stay under the independent tree's id.
- Gauges. The snapshot-pin, WAL saturation-state and pin-shed stall gauges fold a logical tree's copies into one series under its id: counts such as snapshot pins are summed, and the WAL saturation state reports the worst state among the copies (the materialiser pin-shed stall age likewise reports the longest run per pin shard). Per-copy state is never merged, so each copy's own WAL saturation state still governs its own writes.
- Series under the physical id. Some series are tagged with the raw id of
the physical copy rather than the resolved logical id, so after a resize,
restore or remediation they appear under the copy's id. The WAL garbage
collector names the WAL it collects, which is written under the physical
copy:
orleans.lattice.wal.entries_trimmed, the per-treeorleans.lattice.wal.gc.*instruments, theorleans.lattice.storage.policy.*series it records, and the scheduler's zero-primes oforleans.lattice.wal.replay.starvation_drive_abandonmentsandorleans.lattice.materialiser.pin.reports_shed(the grain records a real abandonment, and the leaf's cursor reporter a real shed, under the logical id). The WAL storage providers tag their instruments the same way: the storage-provider commit instruments, theorleans.lattice.storage.wal.*compression counters, and the file provider'sorleans.lattice.wal.compactions,orleans.lattice.wal.compaction.*andorleans.lattice.wal.recovery.*instruments. On the leaf side, the gaugesorleans.lattice.leaf.split.completion.in_flight,orleans.lattice.leaf.split.completion.oldest_age,orleans.lattice.wal.replay.permit_waits_in_flight,orleans.lattice.wal.replay.permit_wait.oldest_ageandorleans.lattice.leaf.snapshot.segment_peak_bytesare keyed by the physical id and are not folded, the zero-primes oforleans.lattice.leaf.replay_barrier_outcomesuse the physical id while its outcomes use the logical id, and the frozen-baseline replay recordsorleans.lattice.wal.replay.slice_narrowingsunder the physical id.orleans.lattice.saturation.refusalscarries the refusing seam's own id, which is the physical copy's for awal_admissionorreplay_permit_admissionrefusal, and the client-sideorleans.lattice.scan.stall_resumptionsandorleans.lattice.scan.stall_futility_outcomestake the physical id the stall exception carries. - Storage-usage and admission gauges.
orleans.lattice.storage.wal_bytes,snapshot_bytes,leaf_state_bytes,total_bytes,usage_deep_publishedandpolicy.over_threshold, and the admission gaugesorleans.lattice.admission.live_keys,estimated_bytes,over_advisoryandutilization, are published by the tree's storage-usage aggregators under the logical id rather than under a copy's id (issue #4152).ILattice.GetStorageUsageAsyncand the admission write guard address the aggregator by the logical id, which measures the live copy. The background storage-usage poller and the cluster roll-up (ILatticeAdmin.GetTotalStorageUsageAsyncandRefreshStorageUsageAsync) still walk every registered tree id, the copy's included, and the copy's own aggregator measures the same shards and WAL - but it publishes under the logical id the copy was derived from, not under its own. Where both run on one silo, the copy's publish overwrites the logical tree's series instead of adding a second one. The aggregators are placed independently, though - and so are a tree's WAL-only and deep aggregators, aliased or not - so on a multi-silo cluster more than one silo can export a series under the sametreevalue, and a cross-silosum by (tree)then double-counts that tree wheremax by (tree)does not. The one exception to the logical id isorleans.lattice.storage.policy.over_threshold, which the WAL garbage collector also sets after each byte-pressure evaluation under the id of the WAL it collects (see Series under the physical id above), so that one gauge can still carry a series under the copy's id. - Tenant. The derived
tenantlabel is unchanged: a physical copy's id keeps its tree's tenant prefix, so both resolve to the same tenant. - System trees.
_lattice_trees are never aliased and keep their own id.
The WAL is still written under the physical tree, and a tree's mutation observers receive the logical id on the same terms.