Note that
popHealth takes no window. The region table is a
current view of the PoP mesh, while the KPI cards, chart, and
histogram are all window-scoped. Comparing a region row against a KPI
card over a 30-day window will not reconcile.
The QoE metric set
qoeKpis returns a single bundle for the selected window. The console
renders each field as-is; it does no arithmetic beyond unit formatting.
A latency field that comes back as
0 is treated as no sample, not
as zero milliseconds: the card and the percentile chip render —. This
matters when you narrow the window on a stream that was idle for most
of it. An em dash means the procedure had nothing to summarise, not
that latency was perfect.
Glass-to-glass latency and the 250 ms target
Glass-to-glass is the end-to-end figure: capture through the ClutchCall relay mesh to the viewer’s decoded frame. It is the number the product is sold on, so it is the only KPI on this screen that carries an explicit target — the P50 glass-to-glass card is annotated250ms.
Read the target against P50 only. The other percentiles are
deliberately unannotated: P90/P95/P99 describe your tail, which is
dominated by individual viewers’ last-mile conditions rather than by
relay behaviour, and they are there for shape, not for pass/fail.
The G2G component in each region row applies the same colour scale to
that PoP’s g2g_p50_ms, which is what lets you tell “the whole window
is slow” apart from “one PoP is slow”.
Rebuffer ratio and first frame
Rebuffer ratio is reported as a percentage with the hintMoQ path.
It is a property of sustained playback: it tells you how much of the
window viewers spent stalled rather than playing. The console prints it
to two decimals precisely because healthy values live below the first
decimal place, and a jump from 0.01 to 0.40 is the signal you care
about.
First frame is the startup counterpart, in milliseconds: time until
the viewer sees anything at all. The two move independently. A good
first frame with a rising rebuffer ratio points at sustained delivery
capacity. A clean rebuffer ratio with a slow first frame points at
session setup.
Both fall back to — under the same rule as the latency fields:
first_frame_ms of 0 renders as no sample.
Unique viewers and watch time
unique_viewers is a de-duplicated count for the window, not a sum of
concurrent-viewer samples. Because de-duplication happens per window,
the counts are not additive across windows: the 7-day figure is not
the sum of seven 24-hour figures, and a viewer who returns on three
days counts once in the 7-day number.
Watch time arrives as watch_minutes in viewer-minutes. The console
switches units for readability once the value reaches 60 minutes:
- below 60 → printed in
minas an integer count of viewer-minutes - 60 or above → divided by 60 and printed in
hto one decimal
1.5 h and the header card showing min are the same unit
underneath.
To reconcile viewers against latency over time, use the twin chart
rather than these cards: it plots viewers per bucket against
g2g_p50 per bucket, each normalised to its own maximum. The left
series (filled, solid) is viewers; the right series (dashed) is P50
latency. Because each scale is independent, the chart shows shape —
whether latency stays flat as viewers climb — and not a shared
magnitude. The chart renders “No viewer/latency samples yet.” when the
series has fewer than two buckets, or when every bucket is zero on both
series.
Glass-to-glass distribution histogram
g2gHistogram returns a buckets array for the same window. The
console renders the first 15 buckets and places a marker on the
bucket containing the window’s P50, computed as floor(g2g_p50_ms / 40)
clamped to the last rendered bucket. Buckets are therefore 40 ms wide,
the rendered axis spans 0–600 ms, and the final column is labelled
600+ because it absorbs everything above the axis.
Two empty states are distinct here:
- No buckets returned — the histogram draws 15 zero-height columns. The axis is still there; there is simply no distribution.
- No P50 (
g2g_p50_msis0) — the marker is suppressed. You can get a drawn distribution with no marker if the bundle and the histogram disagree about having samples.
Per-PoP rows: cache hit, health and status
Each row of By edge region is one PoP frompopHealth, keyed by
code and labelled with its city. Viewers are routed to the nearest
PoP, so the row set reflects where your audience actually was.
Two behaviours are worth knowing before you read a row:
Watch time gates the quality columns. If
watch_minutes is zero or
absent, both Watch time and Rebuffer render —. A PoP with
connected viewers but no accumulated watch time shows a viewer count
and a dash for rebuffer; that is the intended reading, because a
rebuffer percentage over zero minutes of playback is meaningless.
Cache hit and status are independent signals rendered in one cell.
The Health bar’s width is the cache hit ratio; its colour is the
status:
So a short green bar is a healthy PoP with a poor cache hit ratio
(viewer requests mostly missing at the edge), while a long red bar is a
PoP that was caching well and is now not serving. Do not read bar
length as health.
When no PoPs have reported, the table shows “No PoP activity yet —
region rows populate once viewers connect through the relay mesh.”
When telemetry is unavailable
popHealth returns a telemetry_ok flag alongside the rows. When it
is false, two things change:
- The telemetry health banner appears above the KPI cards.
- The By edge region hint changes from
routed to nearest PoPtorouted to nearest PoP · telemetry unavailable — cache/viewer figures may be stale.
telemetry_ok comes only from popHealth.
Time windows and bucket sizes
The Range chip cycles through three windows in order, and every query on the screen re-runs when it changes:
The bucket size scales with the window so the twin chart keeps a
readable number of points. Only
viewerSeries takes bucketSeconds;
qoeKpis and g2gHistogram receive the window alone and return a
single summary over it.
Widening the range therefore coarsens the chart and the CSV at the same
time. A latency spike that is visible as a 10-minute bucket at 24h
can be averaged away inside a 6-hour bucket at 30d.
CSV export
Export CSV downloads the series currently loaded in the twin chart — the same window and the same bucket size, one row per bucket:- The header names the latency column
g2g_p50_ms, while the procedure field isg2g_p50. Values are milliseconds either way. - The filename is
stream-analytics-<range>.csv, where<range>is24h,7d, or30d. - The export is client-side over already-fetched rows. It contains no
percentiles, no histogram, and no per-PoP data — only what the chart
plots. For the region breakdown, read
streams.analytics.popHealthdirectly. - The button is disabled while the series is empty, so a failed or
still-loading
viewerSeriescannot produce a header-only file.
Why the delivery path panel shows no percentage
The Delivery path panel states that all viewer traffic rides Media-over-QUIC over WebTransport. It is a fixed statement of the delivery architecture, not a measured share: there is no HLS or WebRTC fallback path for viewers to split across, so there is no ratio to report and the panel deliberately renders no percentage bar. This is also why the Rebuffer ratio card is hintedMoQ path — it
describes the one path every viewer is on.
Related
- Telemetry — the metric, trace, and CDR streams behind these panels
- Telephony Metrics — definitions for the percentile and quality vocabulary used here

