Struct TickTelemetry
Per-tick telemetry snapshot. Recorded at the end of each tick into the TickTelemetryRing.
public struct TickTelemetry
- Inherited Members
Fields
ActiveSystemCount
Number of systems that actually executed (not skipped) this tick.
public int ActiveSystemCount
Field Value
ActiveWorkerCount
Number of worker threads active during this tick.
public int ActiveWorkerCount
Field Value
ActualDurationMs
Actual wall-clock tick execution time (reset → completion), in milliseconds.
public float ActualDurationMs
Field Value
CurrentLevel
Current overload response level for this tick.
public OverloadLevel CurrentLevel
Field Value
EventQueueDepth
Total pending events across all event queues at tick end. Sustained growth indicates backlog.
public int EventQueueDepth
Field Value
LostWakes
Lost wakes caught this tick: a parked worker's between-tick backstop (50 ms) fired after a dispatch whose Set never reached it. Non-zero means the wake protocol is broken; zero does not prove it is not, since a lost wake that the next dispatch's Set rescues before the backstop leaves nothing to count. Counted when caught, so a wake lost late in one tick lands in the next. Cumulative: LostWakeCount.
public int LostWakes
Field Value
OverrunRatio
Ratio of actual to target duration. Values > 1.0 indicate overrun. Used by overload management (#201) to detect sustained overruns.
public float OverrunRatio
Field Value
TargetDurationMs
Target tick duration based on BaseTickRate (e.g., 16.67ms at 60Hz).
public float TargetDurationMs
Field Value
TickIntervalMs
Actual tick-to-tick interval in milliseconds (time from previous tick start to this tick start).
This is the true period seen by the simulation. Compare against TargetDurationMs to measure jitter: |TickIntervalMs - TargetDurationMs|.
Zero for the first tick.
public float TickIntervalMs
Field Value
TickMultiplier
Tick rate multiplier (1 = normal, 2+ = modulated under Level 3).
public int TickMultiplier
Field Value
TickNumber
Monotonically increasing tick number (0-based).
public long TickNumber
Field Value
TotalEntitiesDeferred
Total entities deferred (budget-capped) across all systems this tick. Zero until Level 2 enforcement.
public int TotalEntitiesDeferred
Field Value
TotalEntitiesProcessed
Total entities processed across all systems this tick.
public int TotalEntitiesProcessed
Field Value
UowFlushMs
Wall-clock time this tick spent in the Unit-of-Work flush, in milliseconds — which in WAL mode is
WalManager.RequestFlush followed by WaitForDurable, i.e. the tick's DURABILITY WAIT (#CLI-04).
public float UowFlushMs
Field Value
Remarks
A wall-clock span, not CPU, and not a per-commit figure. The tick driver blocks here until the WAL writer has
published the tick's records, so this is the latency a tick pays for durability. The per-COMMIT wait is a different
population: it is measured inside WalWriter.WaitForDurableSlow, has no always-on accumulator, and its fast
path (already durable) returns without touching a timer at all. A consumer reporting this as
typhon.durability.wait.p99 must say which of the two it means.
Why here rather than on a profiler span. The flush is already wrapped in a TickPhase.UowFlush span, but
a span exists only while the profiler is recording: with the profiler off the wrapper folds away and the number does
not exist, which is exactly why the metric emitted a hard zero before this field. The ring is single-writer from the
tick driver and stamped at tick end, so carrying it here costs one Stopwatch pair per tick — on a path that
just waited on an fsync — and no synchronisation at all.
Zero is a real reading: a tick whose records were already durable, or one that committed nothing, genuinely waited for nothing. It is not "unknown". (It is also zero for a tick that did not reach its flush at all — see the clear at the top of the scheduler's tick driver, which is what keeps a failed flush from donating its wait to the next tick.)