The Overview screen is the Streams developer home. It is a snapshot screen: every panel is a short, cheap query that refreshes on its own timer. The Analytics screens are the place for exact, windowed numbers. This page explains where each Overview figure comes from so you can tell a real change from a refresh-timing artefact. Every query on this screen is scoped to the org id from the current tenant context and is disabled until that org id resolves.

The five KPI tiles and where each figure comes from

The KPI strip across the top is fed by streams.analytics.overviewKpis, with one exception — the Live streams tile, which is counted client-side from a page of streams.liveInputs.list. Two things to note about the Concurrent viewers tile. The number is the analytics rollup’s viewers_now. The across N live streams subtitle next to it is not from the same query — it is the same client-side count that drives the Live streams tile. The two can disagree briefly after a stream starts or stops, because they refresh independently. The total denominator on the Live streams tile comes from a separate, deliberately tiny call: liveInputs.list with perPage: 1, read only for its total. It is cached with a 60-second stale time, so a newly created input can take a moment to move the denominator.

Windows and refresh cadence per panel

The screen does not have one clock. Each panel picks the cheapest cadence that still feels live, so panels drift relative to one another between ticks. The practical consequence: the P50 glass-to-glass KPI tile and the P50 under the histogram are different numbers from different procedures. The tile reads overviewKpis.g2g_p50_ms; the histogram panel reads qoeKpis.g2g_p50_ms over an explicit 60-minute window and refreshes on a different timer. If you need one authoritative percentile, read the latency panel, not the strip.

Why the live stream count can be a floor

The Live streams tile and the across N live streams subtitle sometimes render with a trailing +, for example 12+. That means at least twelve, not exactly twelve. The reason is how liveness is resolved. liveInputs.list filters on the Postgres status column first, then reconciles each returned row against the relay to set is_live. Because that reconcile happens after the database filter, the screen cannot ask the server for “only live rows” and trust the count — it fetches one page of up to 100 inputs and counts the live ones client-side. So the screen compares the number of rows it received against the total reported by the same query:
  • total equals the rows returned → the count is exact, no +.
  • total is greater than the rows returned → there are inputs the page never saw, any of which might be live. The count is a lower bound and the tile appends +.
An org with more than one page of inputs will therefore always see the +, even if nothing is broken. To get an exact live count, open the Live streams screen, which pages through the full set. The Live now panel under the endpoint card is a preview of the same page: it renders the first four live rows with their per-stream viewers_now and g2g_p50_ms. “View all” goes to the full list.

Billing cycle meters when no plan pool is set

The “This billing cycle” card shows three meters. Their used values and their limits come from two different procedures, and the limits are optional. analytics.billing returns a pools object which may contain stream_egress_gb and vod_storage_gb, each with a limit and a remaining. analytics.usage returns raw metered counters: delivery_minutes, egress_bytes and storage_bytes. How each meter resolves:
  • Egress and Storage (VOD) — if the matching pool exists, the meter shows limit − remaining as used (never below zero) against the pool’s limit. If the plan defines no such pool, the meter falls back to the metered counter from analytics.usage, converting bytes to GB by dividing by 1024³, and renders with a limit of zero. All three values are rounded to one decimal.
  • Delivery minutes — always rendered with a limit of zero. This modality has no delivery-minute pool on the Overview screen, so the meter is a counter, not a quota. It shows minutes consumed so far in the current billing cycle and nothing else.
A meter drawn against a zero limit is expected whenever the plan does not carve out a pool for that resource. It does not mean your allowance is exhausted, and it does not mean usage is unmetered — the used figure is still the real metered number. Read the limit as “no pool configured”. Because analytics.billing refreshes every 120 s and analytics.usage every 60 s, a meter can briefly show a used value computed one way and a limit from the previous billing tick. It reconciles on the next refresh.

Reading a dash, a plus, or an empty chart

The screen distinguishes “no data yet” from “zero” in several places. What you see tells you which query is still cold.
  • Em dash (—) in a KPI tile. The underlying query has not returned yet, or returned nothing. The Live streams tile shows a dash specifically while liveInputs.list is loading, then switches to a count.
  • Em dash on P50 / P95 / P99 under the histogram. qoeKpis reported zero for that percentile, which the panel treats as “no samples” rather than “0 ms”. Percentiles only render once the 60-minute window contains latency samples.
  • Trailing + on a count. A lower bound — see Why the live stream count can be a floor.
  • “No viewer samples yet.” The 24-hour viewer chart needs at least two buckets with a non-zero value. Fewer than two 10-minute buckets, or an all-zero series, renders this caption instead of a flat line at zero. A brand new org sees this until the relay rollup produces its second bucket.
  • Flat empty histogram. When g2gHistogram returns no buckets, the panel draws fourteen empty bars so the axis labels stay in place. The P50 marker is hidden in that case; it only appears when qoeKpis reports a non-zero P50.
  • “No active inputs — your first encoder publish will show up here.” The Live now panel has rows available but none of them are live, or the org has no inputs at all.
  • “No webhook deliveries yet.” eventDeliveries.list returned nothing. Once deliveries exist, the panel shows the six most recent with their HTTP response code and event type; a code in the 2xx range renders as success, anything else as a failure.

The histogram bars and the P50 marker

The latency histogram plots the first fourteen buckets returned by g2gHistogram over the 60-minute window, labelled from 80 ms to 600+ ms. The marker showing where your median sits is derived, not returned: the panel takes qoeKpis.g2g_p50_ms, divides by 40 to map milliseconds onto a bucket index, and clamps the result to the last drawn bucket. A median past the top of the axis therefore parks the marker on the final bar rather than disappearing off the edge. Read the marker as approximate and the P50 stat below it as the number.