Diagnostics

July 15, 2026 ยท View on GitHub

ZoneTree diagnostics start with the storage shape: mutable segment, read-only segments, DiskSegment, bottom segments, WAL, caches, and maintenance activity.

Use this page to decide what to measure before tuning or troubleshooting.

Core Counters

Maintenance exposes the fastest view of the current LSM shape.

CounterWhat It Tells You
MutableSegmentRecordCountrecords currently in the writable mutable segment
ReadOnlySegmentsCountfrozen in-memory segments waiting for merge
ReadOnlySegmentsRecordCountrecords waiting in read-only in-memory segments
InMemoryRecordCountmutable plus read-only segment records
TotalRecordCountphysical records across segment layers
IsMergingnormal merge is running
IsBottomSegmentsMergingbottom segment merge is running
BottomSegments.Countnumber of bottom disk segments

TotalRecordCount is a physical storage-shape counter. It can include older versions and deletion markers until merge removes them. Use Count() or CountFullScan() when you need live-record count.

Segment Movement Events

Events are the cleanest way to log segment movement without polling.

EventUse
OnMutableSegmentMovedForwardmutable segment became read-only
OnMergeOperationStarted / OnMergeOperationEndednormal merge timing and result
OnBottomSegmentsMergeOperationStarted / OnBottomSegmentsMergeOperationEndedbottom merge timing and result
OnDiskSegmentCreatednew disk segment files were created
OnDiskSegmentActivatednew disk segment became part of the tree shape
OnCanNotDropReadOnlySegmentcleanup could not drop a read-only segment
OnCanNotDropDiskSegmentcleanup could not drop a disk segment
OnCanNotDropDiskSegmentCreatortemporary merge output cleanup failed
zoneTree.Maintenance.OnMergeOperationEnded += (_, result) =>
{
    Console.WriteLine($"Merge ended: {result}");
};

zoneTree.Maintenance.OnMutableSegmentMovedForward += tree =>
{
    Console.WriteLine(
        $"read-only segments={tree.ReadOnlySegmentsCount}, " +
        $"in-memory records={tree.InMemoryRecordCount}");
};

Failed drop events mean ZoneTree could not delete obsolete segment files, WAL files, or temporary merge output after the logical tree shape had moved forward. Keep the exception details and investigate the storage/provider error; the event usually indicates cleanup debt rather than a corrupted active tree.

Logger Signals

Configure a logger in production and retain logs around:

  • failed merges,
  • failed drops,
  • WAL read errors,
  • recovery warnings,
  • live backup failures,
  • unusually long maintenance operations.
using ZoneTree.Logger;

using var zoneTree = new ZoneTreeFactory<int, string>()
    .SetDataDirectory("data/app")
    .SetLogger(new ConsoleLogger(LogLevel.Info))
    .OpenOrCreate();

Write Pressure

Watch these when write throughput or memory changes:

SignalMeaning
rising MutableSegmentRecordCountcurrent mutable segment is filling
rising ReadOnlySegmentsCountmaintenance is not merging as fast as segments move forward
long merge durationmerge IO, compression, serialization, or payload size is expensive
large WAL filesin-memory segments are not yet merged, or WAL history is intentionally retained

Useful context:

  • MutableSegmentMaxItemCount,
  • value size,
  • WAL mode,
  • serializer cost,
  • storage write throughput,
  • maintainer settings.

Read Path

For disk reads, inspect:

SignalMeaning
segment countshow many layers may be searched
DefaultSparseArrayStepSizesparse index density
BlockCacheLifeTimehow long inactive decompressed disk blocks stay cached
InactiveBlockCacheCleanupIntervalhow often inactive cache cleanup runs
disk compression block sizerandom-read granularity and cache unit size
iterator cache contributionwhether scans populate the shared block cache
circular key/value cache settingsrepeated same-record key/value reuse

For compressed disk segments, decompressed block cache behavior is usually more important than circular key/value caches.

See read-path caching.

Memory

OS process memory is not the same thing as live ZoneTree data. .NET may keep freed memory available for reuse.

Measure:

  • live managed object size,
  • allocation rate,
  • large object heap usage,
  • retained references,
  • iterator lifetimes,
  • mutable/read-only segment sizes,
  • decompressed block cache lifetime.

Common ZoneTree levers:

  • MutableSegmentMaxItemCount,
  • value size,
  • maintainer cleanup,
  • BlockCacheLifeTime,
  • iterator lifetime.

WAL And Recovery

Track:

  • WAL directory size,
  • recovery duration,
  • incomplete WAL tail reports,
  • checksum or deserialization failures,
  • serializer/comparer compatibility.

An incomplete tail after process termination is a normal recovery boundary. Checksum and deserialization failures are integrity signals and should be investigated.

See recovery and WAL modes.

Backup

For live backup, measure:

  • generation duration,
  • failed generation logs,
  • file transfer duration,
  • record batch size,
  • local retention behavior,
  • restore test results.

Live backup is generation based. A generation contains disk segment files and optional in-memory records for that backup point.

See backups.

Benchmark Shape

When recording benchmark or incident data, include:

  • key and value type,
  • serializers,
  • comparer,
  • WAL mode,
  • disk segment mode,
  • compression settings,
  • mutable segment size,
  • multipart min/max record count,
  • DiskSegmentMaxItemCount,
  • sparse array step size,
  • block cache lifetime,
  • storage hardware,
  • maintainer settings,
  • backup activity.

Without the shape, numbers are hard to compare.