The Honest Stopwatch
Most timing code starts casually -- a clock() before, a clock()
after, a subtraction -- and inherits three quiet defects. The clock is
coarse (CLOCKS_PER_SEC granularity). The clock may be a wall clock,
which jumps when NTP corrects the machine's time -- so a measurement
spanning that correction is silently wrong, occasionally even negative.
And the older Softanza surface compounded it by answering in prose:
StzElapsedTime() returns the string "0.123 second(s)" -- pleasant
to read, useless to compare, add, or assert on.
by Mansour Ayouni · in the repository since 2026-07-29 · design essay · area Performance
Numeric, monotonic, unlimited -- and fluent in OpenTelemetry
Every code block below is real, and every output block is its actual output (the run lives in
base/test/perf/_narration_demo.ring; the guard suite isbase/test/perf/stopwatch_narrated.ring, 35 assertions). Part of the performance system's P0 --doc/design/SOFTANZA_PERF_SYSTEM.md.
The problem with asking a program what time it is
A stopwatch is an instrument. An instrument owes you a number, from a clock that only moves forward.
One object, starting the moment you create it
stzStopwatch (in base/perf/) reads the engine's monotonic watch
clock -- nanosecond precision, anchored at DLL load, immune to
wall-clock jumps. You create it when you start measuring:
w = StzStopwatchXT("import-orders") # StzStopwatch() for unnamed
# ... parse two hundred thousand items ...
? w.ElapsedMs()illustration
13.42
A number. Milliseconds are the house unit (Elapsed() says the same
thing); ElapsedNs(), ElapsedUs(), ElapsedS() name other units in
the verb, so the reader of the call site knows what scale arrived
without consulting a manual.
Laps split, Pause excludes, Stop closes
A lap is a labeled split reading -- the clock keeps running. A pause excludes time from the measurement: the stopwatch holds its breath while you await something you do not want counted. Stop freezes the reading and closes the measurement's time window:
w.Lap("parsed")
# ... more work ...
w.Lap("validated")
w.Pause()
StzEngineTimeSleepMs(100) # NOT ours -- excluded
w.Resume()
# ... final stretch ...
w.Stop()
? w.ElapsedMs()illustration
27.73
And the object can say what it saw:
w.Show()
illustration
Stopwatch import-orders -- stopped. Elapsed: 27.73 ms (monotonic engine clock). Laps (2): 1. parsed at 13.56 ms 2. validated at 20.47 ms
The record: data first
Record() returns the measurement as a plain hashlist -- the
Softanza-native shape every later perf layer (metrics, SLA checks)
consumes:
aRec = w.Record() ? aRec[:name] ? aRec[:durationMs] ? aRec[:running]
illustration
import-orders 27.73 0
Speaking OpenTelemetry -- the industry handshake
A performance system that can only talk to itself is a silo. A stopped stopwatch exports as an OpenTelemetry span -- the lingua franca of Jaeger, Grafana Tempo, Datadog, and every OTLP collector -- with a real W3C trace identity generated by the engine's trace-context module:
? w.ToOtelJson()
illustration
{"name":"import-orders","traceId":"3df740863b1ad8809baa7788e62ade6a","spanId":"35ff1af4f292037b","kind":"SPAN_KIND_INTERNAL","startTimeUnixNano":"1785318565258000000","endTimeUnixNano":"1785318565393000000","attributes":[{"key":"stz.duration_ns","value":{"doubleValue":27725100}}],"events":[{"name":"parsed","timeUnixNano":"1785318565272000000"},{"name":"validated","timeUnixNano":"1785318565279000000"}]}Read it closely -- there is a counter-intuitive fact in those numbers.
The span's wall window is 393 - 258 = 135 ms, but the measured
duration is 27.7 ms. Both are right: the window includes the 100 ms
pause (the span records when the work happened, in absolute time),
while the duration counts only the measured stretches, on the
monotonic clock. A tracing backend shows you the window; the
stz.duration_ns attribute carries the instrument's exact reading.
Two honest limits, stated rather than hidden. The absolute anchors
(startTimeUnixNano) carry millisecond resolution -- Haro numbers
are 64-bit floats, and epoch nanoseconds exceed their exact-integer
range, so the engine hands over exact epoch millis and the string gains
six zeros. The exact nanosecond duration rides in the attribute,
where it fits comfortably. And ToOtelSpan() (the hashlist twin) is
the span alone -- batching spans into a full OTLP resourceSpans
envelope is the P2 exporter's job, when metrics join.
Distributed correlation comes free from the same identity:
? w.TraceParent()
w2 = StzStopwatchXT("notify-customer")
w2.JoinTrace(w.TraceParent()) # same trace, new span
w2.Stop()
? w2.TraceId() = w.TraceId()illustration
00-3df740863b1ad8809baa7788e62ade6a-35ff1af4f292037b-01 1
Hand TraceParent() to a downstream call (it is exactly the W3C
traceparent header; stzHttpClient.SetTraceParent() injects it) and
the two spans reunite in any tracing backend as parent and child.
The clock underneath -- and the bug that was there
The engine's watch module (engine/src/watch.zig) used to read
std.time.nanoTimestamp() -- wall-clock UTC since 1970. That is the
same defect the process-uptime fix removed a while ago: a wall clock
jumps when the OS corrects time, and a stopwatch spanning the jump
lies. P0 gave the watch module the identical cure: a monotonic
Instant baseline captured at DLL load. The tell is one read:
? StzEngineWatchTimestampMs()
illustration
177.46
177 ms since the module loaded -- not 1.7 trillion ms since 1970. The guard suite pins this property permanently, the same way the process-uptime guard does.
Worth knowing, too: stopwatch state lives in the object (two clock
readings and a sum), not in the engine's 64-slot watch table -- so
instances are unlimited, independent, collision-free, and there is
nothing to Destroy(). The guard runs 70 at once to make the point.
Where this goes
The stopwatch is the first brick of the performance system
(SOFTANZA_PERF_SYSTEM.md): P1 teaches the engine to observe memory
and CPU, P2 turns readings into named metric streams with percentiles,
P4 judges them against SLAs declared at design time, P5 explains them
through operational analysis. The stopwatch stays what it is -- the
honest instrument everything above it trusts.
Proved by
The article names these scenario guards of the library:
Cite
Mansour Ayouni. "The Honest Stopwatch". Softanza narrations, 2026. https://mayouni.github.io/stzsite/en/narrations/stz-honest-stopwatch-narration.html
Not run: its code touches files, the network, the clock or chance. The article is published as written; its blocks are illustrations. The code of the articles is Haro code. Where an article was written before the language took its present name, the name was changed and nothing else. Genre, area and series read from the file's name, the year from its first commit: derived, until the article carries its own header. The file on GitHub(opens in a new tab)

