---
title: "Serializable types - Lattice Public API Reference"
url: "https://nsta1.github.io/Orleans.Lattice/docs/lattice/api/serializable-types.html"
source: "https://github.com/NSTA1/Orleans.Lattice/blob/release/9.9/docs/lattice/api.md?plain=1#L2496-L2574"
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"
---
# Serializable types

Part of [Lattice Public API Reference](../api.md).

All serializable types - and every grain interface, including the
public `ILattice` - carry stable `[Alias]` attributes (prefixed
`ol.`) to ensure wire-format and grain-manifest compatibility across
versions. Alias constants live in `TypeAliases` and must never be
renamed or removed: they are part of the public wire format.

Types marked `public (hidden)` below are annotated with
`[EditorBrowsable(EditorBrowsableState.Never)]`. They remain `public`
for Orleans code generation but are hidden from IntelliSense because
they are implementation details not intended for direct use. Types
marked `internal` are not part of the public surface at all - only
their aliases are wire-format contracts.

The table lists the core wire types most callers meet; it is not
exhaustive. Every other public serializable type in this reference
(cursor pages and specs, mutation-observer and saturation-signal
payloads, orphaned-leaf reports, CRDT state and delta types, and so on)
carries an `ol.` alias too.

| Type | Alias | Visibility | Description |
|------|-------|------------|-------------|
| `HybridLogicalClock` | `ol.hlc` | public (hidden) | Hybrid logical clock for conflict-free timestamps. See [State Primitives](../state-primitives.md). |
| `LwwValue<T>` | `ol.lwv` | internal | Last-writer-wins register. |
| `VersionVector` | `ol.vv` | public | Causal version vector (pointwise-max merge). |
| `StateDelta` | `ol.sd` | internal | Delta of changed entries for replication. |
| `SplitResult` | `ol.sr` | internal | Result of a node split. |
| `KeysPage` | `ol.kp` | internal | Paginated batch of keys from a shard scan. |
| `EntriesPage` | `ol.ep` | internal | Paginated batch of key-value entries from a shard scan. |
| `TreeRegistryEntry` | `ol.tre` | internal | Per-tree metadata record. |
| `SnapshotMode` | `ol.snm` | public | Enum: `Offline`, `Online`. |
| `TreeResizeState` | `ol.trs` | internal | Persistent state tracking resize progress. |
| `ResizePhase` | `ol.rp` | internal | Enum: `Snapshot`, `Swap`, `Cleanup`, `Reject`. |
| `TreeSnapshotState` | `ol.tss` | internal | Persistent state tracking snapshot progress. |
| `SnapshotPhase` | `ol.snp` | internal | Enum: `Lock`, `Copy`, `Unmark`, `ShadowBegin`. |
| `TreeDeletionState` | `ol.tds` | internal | Persistent state for soft-delete / purge tracking. |
| `TreeMergeState` | `ol.tms` | internal | Persistent state tracking merge progress. |
| `CasResult` | `ol.cas` | internal | Result of a compare-and-swap operation. |
| `VersionedValue` | `ol.vvl` | public (hidden) | A `byte[]` value paired with its `HybridLogicalClock` version. |
| `Versioned<T>` | `ol.ver` | public | A typed value paired with its `HybridLogicalClock` version (used by typed extensions). |
| `ShardHotness` | `ol.sh` | internal | Volatile shard hotness counters. |
| `ShardMap` | `ol.sm` | public | Per-tree mapping from virtual shard slots to physical shard indices. |
| `RoutingInfo` | `ol.ri` | public (hidden) | Per-activation routing snapshot returned by `ILattice.GetRoutingAsync()`. |
| `ShardCountResult` | `ol.scr` | internal | Per-shard count plus the set of virtual slots observed during the count. |
| `PendingMutationSnapshot` | `ol.pms` | internal | Snapshot of a single in-flight prepared mutation used during shard split. See [Shard Splitting](../shard-splitting.md). |
| `LeafProjectionDigest` | `ol.lpd` | public | `readonly record struct` returned by `ILattice.GetLeafProjectionDigestAsync`. Carries the 16-byte XxHash128 hash, entry count, projection checkpoint offset (the maximum across leaves for a shard digest), and a `Version` field stamping the contribution-function shape. Digests with different `Version` values must not be byte-compared. See [Projection Rebuild](../projection-rebuild.md). |
| `ChildDigestSnapshot` | `ol.cds` | internal | `readonly record struct` propagating digest contributions up the tree. |
| `ProjectionRebuildPolicy` | - | public | Enum: `SnapshotThenWal` (default), `FullRebuildFromWal`, `Fail`. See [Configuration](../configuration/options-reference-2.md#projectionrebuildpolicy). |
| `TreeStorageUsageReport` | `ol.tsu` | public | `readonly record struct` returned by `ILattice.GetStorageUsageAsync`. Byte-accurate per-tree storage footprint. |
| `ClusterStorageUsageReport` | `ol.csu` | public | `readonly record struct` returned by `ILatticeAdmin.GetTotalStorageUsageAsync`. Cluster-wide storage roll-up. |
| `SplitActivityReport` | `ol.spa` | public | `readonly record struct` returned by `ILatticeAdmin.GetSplitActivityAsync`. Cluster-wide shard-migration activity (adaptive split sources and consolidation fold donors alike): `InFlight`, `ReportingTrees`, `ObservedAt`, and the `AnyInFlight` projection the autoscaling scale-in gate reads. |
| `ShardStorageUsage` | `ol.ssu` | internal | `readonly record struct` per-shard leaf-state + snapshot byte roll-up. |
| `LatticeShuttingDownException` | `ol.lsd` | public | Typed `InvalidOperationException` subclass thrown by `ILattice` operators (and the atomic-write saga coordinator) when an operation cannot complete because the owning silo's WAL writer is draining as part of host shutdown. See [Shutdown back-pressure](shutdown-back-pressure-latticeshuttingdownexception.md) and [Atomic Writes](../atomic-writes.md). |
| `WalPlacement` | `ol.wpl` | public | `readonly record struct` returned by `ILatticeAdmin.GetWalPlacementAsync`. A tree's durable WAL placement pin: `TreeId`, the default catalogue key (`DefaultProviderKey`), the per-partition overrides (`Partitions`), and the compare-and-swap `Version`. See [WAL Storage Providers](../wal-storage-providers.md#multi-account-fan-out-named-providers-and-pinned-placement). |
| `WalPartitionPlacement` | `ol.wpe` | public | `readonly record struct` - one partition's resolved catalogue key inside a `WalPlacement` / `WalPlacementAudit` (`Partition`, `ProviderKey`, `ResolvableOnThisSilo`). |
| `WalPlacementAudit` | `ol.wpa` | public | `readonly record struct` returned by `ILatticeAdmin.AuditWalPlacementAsync`. Placement plus per-silo resolvability of every pinned key: `TreeId`, `Version`, `PartitionCount`, `Partitions`, `AllResolvableOnThisSilo`, and the serving silo's `KnownProviderKeys`. |
| `WalMovePlan` | `ol.wmp` | public | `readonly record struct` returned by `ILatticeAdmin.PlanWalMoveAsync`. Read-only dry run of a partition move: `TreeId`, `Partition`, `FromProviderKey`, `ToProviderKey`, `PlacementVersion`, `SourceLowestOffset`, `SourceHighestOffset`, `EntriesToCopy`, `TargetResolvableOnThisSilo`, and `AlreadyAtTarget`. |
| `WalMoveBatchPlan` | `ol.wbp` | public | `readonly record struct` returned by the batch `ILatticeAdmin.PlanWalMoveAsync`. Wraps one `WalMovePlan` per partition (`Moves`) plus `TreeId`, `PlacementVersion`, and `AllTargetsResolvableOnThisSilo`. |
| `WalMoveOptions` | `ol.wmo` | public | `readonly record struct` tuning a move (`QuiesceLease`, `CopyPageSize`, `VerifyAfterCopy`, `MaxConcurrentPartitionMoves`); `WalMoveOptions.Default` for the defaults. A non-positive value falls back to its default through the `EffectiveQuiesceLease` / `EffectiveCopyPageSize` / `EffectiveMaxConcurrentPartitionMoves` projections (`DefaultQuiesceLease` 30 s, `DefaultCopyPageSize` 256, `DefaultMaxConcurrentPartitionMoves` 1). |
| `WalMoveReceipt` | `ol.wmr` | public | `readonly record struct` returned by `ILatticeAdmin.ExecuteWalMoveAsync` / `ReclaimMovedWalSourceAsync`. Records the offset range copied, the new pin version, and the move `Outcome`: `TreeId`, `Partition`, `FromProviderKey`, `ToProviderKey`, `PreviousPlacementVersion`, `NewPlacementVersion`, `CopiedFromOffset`, `CopiedThroughOffset`, `SourceHighestOffset`, `TargetHighestOffset`, `SourceRetained`, and `Outcome`. |
| `WalMoveBatchReceipt` | `ol.wbr` | public | `readonly record struct` returned by the batch `ILatticeAdmin.ExecuteWalMoveAsync`. Wraps one `WalMoveReceipt` per partition (`Moves`) plus the single placement-version transition the batch applied (`PreviousPlacementVersion`, `NewPlacementVersion`), `TreeId`, and `Outcome`. |
| `WalMoveOutcome` | `ol.wmc` | public | Enum: `Moved`, `AlreadyAtTarget`, `SourceReclaimed`, `NoOp`. The terminal disposition of a move / reclaim call. |
| `LatticeSaturatedException` | `ol.lsa` | public | Typed `InvalidOperationException` subclass raised by seven seams - the WAL writer admission gate, the atomic-write saga coordinator, the snapshot-cursor open path, the per-silo replay-permit admission gate, the `SetManyAsync` shard fan-out, the `SetManyAsync` whole-call envelope, and the transaction-registry row-size admission bound - when an operation is refused because the tree's storage layer is back-pressured. Carries the originating `TreeId` and a `SaturationSource` naming the refusing seam. See [Saturation back-pressure](saturation-back-pressure-latticesaturatedexception.md) and [WAL Saturation Signal](../wal-saturation-signal.md). |
| `LatticeSaturationSource` | `ol.lso` | public | Enum: `Unspecified`, `WalAdmission`, `AtomicWriteSaga`, `SnapshotCursorOpen`, `ReplayPermitAdmission`, `SetManyFanOut`, `TxRegistryCapacity`, `SetManyEnvelope`. Names which seam raised a `LatticeSaturatedException`, so a handler can retry the members that are safe to retry and propagate the rest. Retrying `WalAdmission` below the routing layer re-fans a batch across every shard, so the distinction is load-bearing. See [Saturation back-pressure](saturation-back-pressure-latticesaturatedexception.md). |
| `LatticeQuotaExceededException` | `ol.lqe` | public | Typed `InvalidOperationException` subclass thrown when a locally-authored write call is refused because the tree reached its configured `MaxLiveKeys` / `MaxEstimatedBytes` admission cap (`Dimension` is `keys`/`bytes`, the `KeysDimension` / `BytesDimension` constants; only the write calls listed under [Admission back-pressure](admission-back-pressure-latticequotaexceededexception.md) check these caps), or - with the optional tenancy add-on registered - because the acting tenant breached an aggregate ceiling (`Dimension` adds `memory`, `trees`, and the transient `ops-per-second`, the `OpsPerSecondDimension` constant; `ops-per-second` is also raised on the read surface, which charges every allowed read against the tenant's request-rate budget). Carries `TreeId`, `Dimension`, `Current`, `Limit`, and `TenantId` (empty for a per-tree cap). See [Admission back-pressure](admission-back-pressure-latticequotaexceededexception.md) and [Metrics](../metrics/instrument-catalog-5.md#per-tree-admission-control). |
| `LatticeIdempotencyKeyMismatchException` | `ol.ikm` | public | Typed `InvalidOperationException` subclass thrown by the atomic-write saga and the cross-tree transaction coordinator when a caller-supplied `operationId` is re-submitted with a different key set (or, cross-tree, a different tree set or key set) than its first submission. A deterministic caller error - distinct from a genuine server-side saga failure - so the API bindings map it to a client-error status. Carries the offending `OperationId`. See [Atomic Writes - Key-set stability](../atomic-writes.md#key-set-stability). |
| `LatticeStateWriteFailedException` | `ol.swf` | public | Typed exception deriving directly from `Exception` (so it does not implement `ILatticeDomainFault`), thrown when an atomic-write saga, a cross-tree atomic-write coordinator, or a WAL materialiser pin shard fails to persist its own durable state. It replaces the storage provider's exception at the grain boundary, so a client always receives a serializable Lattice exception it can load. Carries `GrainType`, `GrainKey`, `FaultType`, and `Conflict` (`true` for a lost optimistic-concurrency check, after which a retry with the same operation id is safe). See [Exception reference](extension-seams-and-supporting-types.md#exception-reference). |
| `LatticeCrdtShapeNotRegisteredException` | `ol.csn` | public | Typed `InvalidOperationException` subclass thrown by the leaf grain's typed CRDT apply and prepared-fold paths when an OR-Map verb targets a tree whose host never registered the `(TKey, TValue)` shape via `ISiloBuilder.AddOrMapShape<TKey, TValue>(treeName)`. A deterministic host-configuration precondition - distinct from a genuine server fault - so the API bindings map it to a client-error status (for example gRPC `FailedPrecondition`). Carries the offending `TreeId`. Closed-shape modes never raise it (they resolve through the global registry fallback). Both paths also raise it - at any mode, with an empty `TreeId` - when the leaf activation has no tree id bound, meaning a CRDT write reached a leaf the owning shard root had not yet attached; that variant names the grain, key, and mode, and is a routing/lifecycle race to retry rather than a missing registration. |
| `LatticeTenantAccessDeniedException` | `ol.tad` | public | Typed `Exception` subclass surfaced at the `ILattice` tenant-resolution boundary when the active-tenant context resolver refuses the caller's asserted active tenant - it fails validation against the caller's own membership, and an anonymous caller can never act as a tenant - or when, under an asserted tenant and outside system origin, the name is a `sys-` tree or a malformed `t/` id that belongs to no tenant. A request that asserts no active tenant resolves the reserved default tenant, whatever the caller's memberships, and is never refused here; a header value that `LatticeActiveTenantAssertion` cannot parse as a tenant id is dropped as no assertion rather than refused. Composing a tenant-scoped tree id is refused rather than silently defaulting. The `ILattice` read and write paths also raise it when an active `ITenantAdmissionController` refuses the operation (see [Exception reference](extension-seams-and-supporting-types.md#exception-reference)). The core no-op resolver always resolves the reserved default tenant and the core admission controller is inactive, so a cluster with no tenancy add-on is unaffected. See [`Orleans.Lattice.Tenancy`](../../lattice.tenancy/README.md). |
| `LatticeReservedTreeNamespaceException` | `ol.rtn` | public | Typed `InvalidOperationException` subclass thrown when a call names a tree inside a reserved, internally-composed namespace - any `ILattice` call to an internal `_lattice_` tree, and a user-origin data mutation or snapshot destination in the `sys-` namespace or a `t/` tenant namespace the caller's active tenant does not own - or, for a user-origin data mutation, the reserved all-trees authorization sentinel (see [Exception reference](extension-seams-and-supporting-types.md#exception-reference)). A deterministic caller-side precondition rather than an authorization failure, so the API bindings map it to a client-error status (the data gRPC binding maps it to `InvalidArgument`). Carries the offending `TreeId`. |
| `LatticeTreeNotRegisteredException` | `ol.tnr` | public | Typed `KeyNotFoundException` subclass, implementing `ILatticeDomainFault`, thrown when a tree-registry verb that changes an existing tree's entry names a tree with no registry entry (never created, or purged); it refuses and creates nothing, so the API bindings report a not-found status. Carries the offending `TreeId` (see [Exception reference](extension-seams-and-supporting-types.md#exception-reference)). |
| `LatticeWriteFencedException` | `ol.wfx` | public | Typed `InvalidOperationException` subclass thrown by the shard-root write path while the target tree is write-fenced for the duration of a cross-cluster saga (for example a restore cutover). Every write that passes a shard's per-key write gate is refused on every shard of the tree - point, batched, conditional and CRDT writes, single-key deletes, and the legs of an atomic write - so none of them can race the cutover; range deletes, bulk loads and merge applies do not consult the fence, and reads are unaffected. Transient back-pressure - the refused mutation never committed, and the fence lifts on the saga's terminal decision or once the bounded cutover deadline passes. |
| `LatticeWalQuiescingException` | `ol.wqx` | public | Typed `InvalidOperationException` subclass thrown by a WAL shard quiesced for an in-progress administrative placement move, so the coordinator can copy a stable log tail and flip the placement pin without racing a writer. Transient back-pressure - the refused append's entries never committed, and the fence releases within the move's quiesce lease. Self-healing: if the coordinator fails mid-move the lease expires and the next activation re-resolves placement from the durable pin. |
| `LatticeWriteRejectedException` | `ol.wrj` | public | Typed `InvalidOperationException` subclass thrown by the public `ILattice` write, CRDT, atomic, and bulk-load surface when a registered `ILatticeWriteInterceptor` **rejects** a value at the pre-commit choke point. Fail-closed: nothing is persisted before it is raised. A dead-letter decision on a single-key write does **not** raise it (the value is diverted and the caller observes normal completion); in an atomic batch both a reject and a dead-letter abort the whole batch and surface here. |
| `LatticeTreeBatch` | `ol.ltb` | public | `readonly record struct` - one tree's slice of a cross-tree atomic write (`TreeId`, `Entries`, optional `Predicate`, optional `EntryDeltas`, optional `EntryDeletes`). Deliberately **not** `[Immutable]` (mutable members). See [Cross-tree atomic writes](cross-tree-atomic-writes.md). |
| `CrossTreeAtomicWriteOutcome` | `ol.cto` | public | Enum: `Committed`, `PreconditionFailed`. Terminal outcome of a cross-tree atomic write. |
| `CrossTreeInFlightObservation` | `ol.cio` | public | `readonly record struct`, `[Immutable]` - a point-in-time observation of one tree's cross-tree delegation state. `InFlightCount` (`int`): cross-tree sagas still delegating a decision on this tree. `RegistrationEpoch` (`long`): monotonically non-decreasing count of distinct cross-tree sagas that ever registered a delegation here, so comparing it across a window detects a saga that both registered and completed inside it. `UnresolvableCount` (`int`): the subset of `InFlightCount` counted only because the coordinator could not be reached, so a persistently non-zero value is a connectivity fault rather than pipelining. Zero on an observation from a node that predates the field. Consumed by the cross-tree-consistent backup fence. |

Previous: [Extension seams and supporting types](extension-seams-and-supporting-types.md). Next: [Tag indexes](tag-indexes.md). Contents: [Lattice Public API Reference](../api.md).
