What it measures
Two numbers, what they are counted from, and the three places you can read them.
The two numbers
One is GPU time: tokens your GPUs computed more than once. One is GPU memory: the same tokens sitting in more than one cache at the same moment. They measure different resources, so they are never added together.
| Number | Resource | What it counts |
|---|---|---|
| Recomputed prefill | GPU time | Tokens that were stored, then evicted or cleared, then stored again on the same engine. Prefill you paid for twice |
| Duplicate KV footprint | GPU memory | The same content resident on more than one rank at the same instant. Copies across engines count here and are never added to the row above |
Both are counted per rank, meaning one engine, one data parallel worker, one cache group. A node average cannot show you that one rank behaves differently from its siblings, and once you have taken the average you cannot get that back.
Why a miss gets a label
A miss on a prompt nobody had sent before and a miss on a block you evicted an hour ago cost the same GPU time, but you would fix them differently. So each miss is labelled when it is classified, and the labels are never merged back together. In the API they come through as the short names in the middle column.
| Label | In the API | Means |
|---|---|---|
| evicted, then recomputed | ETR |
Stored, evicted, stored again on the same engine. |
| recomputed after cache clear | post_clear |
Same shape, but the cache was flushed rather than evicting under pressure. Usually a restart or a config change. |
| first compute (cold) | cold |
Nothing to hit. Computed once, and not counted as recompute. |
| re-admitted | re_admit |
Came back to a tier it had left. |
| engine-labelled reuse | RE |
The engine said it was a reuse. |
| unclassifiable | indeterminate |
Not enough in the stream to say. Counted as its own thing rather than folded into a neighbour. |
What comes attached to every number
Four things, always. There is no way to get a bare number out of this system.
- What it measures, in plain terms.
- How it was computed, naming what went into it.
- Its coverage, which is how much of the window was actually seen.
- Its bound, which is what it is a floor or a ceiling on.
Figures are floors. If telemetry was missing for part of a window, that mass is not counted and it is not guessed at either, so the real number is somewhere above the one you are reading. A stretch nothing was seen for is drawn as unexamined rather than as a zero.
Coverage means two different things
Token-weighted answers "of the tokens this number is about, how many did we see". It qualifies every token figure. Observed time answers "was the tap sending at all". It qualifies none of them.
A fleet can look fully covered on one and sit at 40 percent on the other, in either direction. That is why both are labelled everywhere they appear.
Three places to read a number
All three come off the same query layer, so they cannot disagree with each other.
The dashboard
Fleet overview, each number's trend over time, which ranks are behind it, and a drill down to the individual store records the number came from. The records are the bottom level, and the page says so rather than implying there is more underneath.
An HTTP API
The dashboard is just a client. Figures, ranks, coverage, evidence, the difference between two windows, the fleet roster and delivery accounting are all addressable, and every response says which analysis version produced it.
Your own Prometheus
The numbers on the dashboard are also on the analyzer's /metrics, so you can
alert on them with what you already run. If you want to be paged when recompute goes past five
percent, that is a rule in your Alertmanager, not a feature request to us.
They appear once an analysis pass has run, and refresh each pass after that. Before the first pass they are absent rather than zero.
| Metric | What it is |
|---|---|
infertap_fleet_recompute_tokens |
Tokens recomputed, over the window. |
infertap_fleet_stored_tokens |
Tokens stored over the same window. The denominator below. |
infertap_fleet_recompute_fraction |
Recompute as a share of tokens stored. |
infertap_fleet_duplicate_kv_tokens |
Tokens held in more than one cache at once. |
infertap_fleet_coverage_fraction |
How much of the window the figures above actually saw. |
infertap_fleet_capture_fraction |
How many of the segments your taps wrote actually arrived. |
infertap_fleet_segments_missing_unexplained |
Segments that never arrived and were never declared lost. |
infertap_fleet_frontier_timestamp_seconds |
How far the analysis has got. Alert on this, not on scrape time. |
infertap_fleet_meaning_info |
Carries the analysis version, so you can join on it. Numbers from either side of a version change are not the same quantity. |
Which taps are reporting
Counted per tap run rather than per tap, because a tap that restarts is a new run. A single fleet wide freshness number is useless at scale: one busy tap keeps it green while ninety nine others sit dark.
| Metric | What it is |
|---|---|
infertap_fleet_producer_runs_reporting |
Taps currently sending. |
infertap_fleet_producer_runs_silent_unexplained |
Gone quiet past their own deadline, with no stop record. Page on this one. |
infertap_fleet_producer_runs_departed |
Stopped cleanly. A rolling deploy lands here, so it will not wake anyone. |
infertap_fleet_producer_runs_ungradeable |
Not enough information to judge either way. |
It tells you when it could not measure something
infertap_analyzer_metrics_unmeasured counts how many of the figures above this
scrape failed to produce. A partly blind scrape says so on the same endpoint, rather than
dropping the metric or sending a zero.
That one, plus coverage_fraction and capture_fraction, is what to
check during a trial. They tell you how much of the picture you are actually getting.
What you will not find here
Nothing tells you a number is good, bad or worrying, and no number is converted into money. Whether a figure warrants action depends on what your fleet is for, which we do not know. You can set thresholds, and they are drawn as your line across the measured data, labelled as yours.