Labels and Dimensions
The vs-the-field document called flat metric names this system's most
consequential absence: http.request.ms measured everything, so
"which route is slow?" had no direct answer. P8 closes the gap with
the field's vocabulary -- a metric FAMILY is one name plus declared
label names, and each label-value combination is a CHILD with its own
engine stores:
by Mansour Ayouni · in the repository since 2026-07-31 · series · the performance series · area Performance
One name, many children -- engine-registered, cardinality-bounded, and honest about overflow
Every code block below is real, and every output block is its actual output (the run lives in
base/test/perf/_labels_narration_demo.ring; the guard suite isbase/test/perf/labels_narrated.ring, 29 assertions). Performance system P8 --doc/design/SOFTANZA_PERF_SYSTEM.md.
The gap the comparison named
oF = StzMetricFamily("checkout.ms", :Timer, [ "route", "method" ])
oF.Child([ "/menu", "GET" ]).Record(12)
oF.Child([ "/menu", "GET" ]).Record(18)
oF.Child([ "/pay", "POST" ]).Record(220)
? oF.Child([ "/menu", "GET" ]).ExactPercentile(95)
? oF.Child([ "/pay", "POST" ]).ExactPercentile(95)illustration
children : 3 (incl. the reserved overflow) /menu p95 : 18 ms /pay p95 : 220 ms
A child is a full stzMetric -- exact window percentiles, streaming
buckets, rates, trends -- scoped to its label values.
The registry lives in the engine -- the copy law, one level up
The hard problem was not the label syntax; it was Haro's copy-on-assign, one level up from where P2 met it. Children are created dynamically -- a route first hit after the server copied its monitor -- and a Haro-side child registry would fork per copy: the server's face would know routes the user's face never sees. So the child registry is an ENGINE store, like every other perf truth:
oF2 = oF # a Haro copy oF2.Child([ "/refund", "POST" ]).Record(77) # a child born through the COPY ? oF.Child([ "/refund", "POST" ]).Count() # read through the ORIGINAL
illustration
born through the copy, seen by the original: 1 sample(s)
Each face keeps only a small reconstruction cache of child wrapper objects -- derived state, rebuilt on miss, never the truth.
Cardinality bounded, overflow visible
The field's label systems have a famous failure mode: an unbounded label value (a user id, a raw URL) mints millions of children and takes the monitoring down with the app. A Softanza family takes its bound at birth and RESERVES an overflow child; when the family is full, new label sets route there -- counted, never silently dropped, and visible in the exposition, which is itself the alarm:
oB = StzMetricFamilyXT("api.calls", :Counter, [ "user" ], 64, 4)
# alice, bob, carol fit; dave and erin arrive when the family is full
see oB.PromText()illustration
# TYPE api_calls_total counter
api_calls_total{user="_overflow"} 2
api_calls_total{user="alice"} 1
api_calls_total{user="bob"} 1
api_calls_total{user="carol"} 1One TYPE header for the family, one labeled sample line per child -- the exposition format Prometheus scrapes, quantiles merged into the label braces for timers. The OTLP side renders one metric with one data point per child, labels as attributes.
Per-route truth from real traffic
ObserveRoutes() is Observe() plus a timer family http.route.ms
labeled [method, route, class] -- one child per route the traffic
actually exercises, status-classed (2xx/4xx/5xx) so errors get their
own distribution:
oSrv.ObserveRoutes(oMon)
# ... six real requests across /menu and /order ...
oFam = oMon.MetricQ("http.route.ms")
? oFam.Child([ "GET", "/menu", "2xx" ]).ExactPercentile(95)
? oFam.Child([ "GET", "/order", "2xx" ]).ExactPercentile(95)illustration
/menu p95 : 6.13 ms (3 reqs) /order p95 : 3.23 ms (3 reqs)
Read that output twice -- it contains a lesson. /order does real
work per request; /menu returns a constant string; yet /menu's
p95 is higher. The first request of the run landed on /menu and
paid the connection warm-up. This is exactly what per-route views are
FOR: the aggregate http.request.ms averaged that spike away, and
the labeled view surfaces it. (It is also a reminder from the P5
grind: small samples carry their outliers -- judge distributions,
not anecdotes.)
The flat instruments stay flat -- http_requests_total renders
without braces, byte-identical to P3, and the SLA's well-known
subjects still judge them. An SLA judges CHILDREN, not families:
asking a family for a single Value() refuses with that guidance.
Where this leaves the comparison
The vs-the-field scorecard moves: labels/dimensions shift from "the biggest gap" to shipped -- with two properties the field's label systems lack (an engine-shared child registry that survives value copies, and cardinality bounded by design with a visible overflow bucket). Still absent, still honest: PromQL-style aggregation ACROSS children (sum by route) is a downstream system's job; label-based SLA selection stays child-explicit.
Proved by
The article names these scenario guards of the library:
Cite
Mansour Ayouni. "Labels and Dimensions". Softanza narrations, 2026. https://mayouni.github.io/stzsite/en/narrations/stz-perf-labels-narration.html
Run in Haro's name on 2026-10-08 20:42 inside the library at commit 4a184e6f0, block after block in one process: 0 of 4 blocks kept their promise; the others 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)

