skip to content

What identifies one time series in a dimensional metrics system, and how does adding a metric label change the total count?

level: juniorimportance: must knowfreq 72%

answer

  1. Identity, not decoration
  2. Name plus the whole label set
  3. Labels multiply, they never add
  4. Per-instance labels multiply too
  5. The product is an upper bound

basics

~20 s

A time series is the metric name plus its complete label set; change any label value and it is a different series. Adding a label multiplies the series count by that label's distinct values rather than adding to it.

solid answer

~50 s

In a dimensional metrics system a series' identity is the pair *(metric name, complete label set)*. Every distinct combination of label key/value pairs is its own stored series with its own history of samples, so there is no such thing as one series carrying two values of a label. That makes the arithmetic multiplicative: a counter with 6 door values and 4 result values is 24 series, and adding a third label with 5 values makes it 120, not 29. The product is an upper bound — only combinations that actually occur become series — but it is the number to reason with. The multiplication also covers the labels you did not choose: on 47 hosts running 12 containers each, the collection tier's per-instance labels already multiply everything by 564 before an application label is counted.

code

text · 4 lines
text
gym_checkin_requests_total{site="bristol",door="turnstile-a",result="ok"} 41273
gym_checkin_requests_total{site="bristol",door="turnstile-a",result="denied"} 118
gym_checkin_requests_total{site="bristol",door="turnstile-b",result="ok"} 29604
gym_checkin_requests_total{site="leeds",door="turnstile-a",result="ok"} 18842

go deeper

for a junior

Be ready to state that a time series is the metric name plus its full label set, and that changing any label value produces a different series rather than a variant of the same one.

for a middle

Expect to do the multiplication aloud: multiply the distinct value counts of every label, then explain why the result is an upper bound rather than the exact count.

for a senior

Show that you count the labels the collection tier adds — host, container, environment — because those multiply an application's series across the whole estate before anyone opens a dashboard.

for a principal

Own the rule teams apply before adding a label: what is its ceiling, what is it multiplied by, and will anyone ever filter or group by it. Detail nobody slices by does not earn a dimension.

## The unit a metrics store actually keeps A dimensional metrics system does not store "a metric". It stores **series**, and one series is the pair *(metric name, complete label set)* together with the run of timestamped samples written against that pair. A **metric label** here means a key/value dimension attached to the measurement — `site="bristol"`, `result="denied"` — not a log-stream label and not an orchestrator object label that happens to share the word. The word doing the work is *complete*. The label set is the series' identity, the way a compound primary key is a row's identity. `door_unlocks_total{site="bristol"}` and `door_unlocks_total{site="leeds"}` are not one metric seen two ways; they are two independent series that happen to share a name. Nothing in the store links them. A dashboard adds them together only because a query told it to. Some stores model the metric name as just another reserved label; the identity rule is unchanged either way. Two consequences fall straight out of that: - **There is no "the same series with a different value".** Changing a label value does not update a series, it starts a different one. - **Adding or renaming a label forks history.** The old label set stops receiving samples and a new one begins, so a range query spanning the change sees one series end and another start rather than a continuous line. ## The arithmetic: labels multiply, they do not add Because identity is the whole combination, the number of series a metric can produce is the **product** of the sizes of its label value sets: series <= |values(label_1)| x |values(label_2)| x ... x |values(label_n)| Take a climbing-gym membership platform's turnstile counter, adding one label at a time: | Labels on the metric | Distinct values of the new label | Upper-bound series | |---|---|---| | `site` | 9 | 9 | | `+ door` | 6 | 54 | | `+ result` | 4 | 216 | | `+ membership_tier` | 5 | 1,080 | Each new label multiplies; nothing adds. The instinct that "one more label is one more thing to store" is the most common wrong model in this whole area, and by the fourth label it is wrong by orders of magnitude. Two refinements separate a good answer from a recited one: 1. **The product is an upper bound, not a count.** Only combinations that actually occur in traffic become series. If each `door` exists at exactly one `site`, the real total is far below 1,080 — real label sets are sparse. That is a reason not to panic at a large product, never a reason to skip computing it. 2. **Sparsity only saves you while every factor is finite.** It reduces a product of bounded factors. It does nothing about a factor that grows with traffic, because every new value there is a combination that has now genuinely occurred. ## The labels you did not choose The application picks some labels. The collection tier attaches more, to record where a sample came from: a host or node identifier, a container or replica identifier, a namespace, an environment. Those are multiplied against the application's product across the entire estate. On a fleet of 47 hosts each running 12 containers, every series an application defines exists 564 times before a single application label is counted. The 216-series turnstile counter above is 121,824 series estate-wide. That estate number — not the per-process one the developer sees locally — is what reaches the store, and it is the number that matters when a telemetry budget is halved and someone has to say which metrics get cut. The same multiplication is why a label that looks harmless in one service is not harmless as a convention. A team-wide "add `build_id` to everything" decision multiplies every metric in the estate at once. ## Where the model gets misapplied - **Counting label *keys* instead of label *values*.** Four labels is not four times the cost; it is the product of their value counts. - **Assuming aggregation makes the count irrelevant.** A query that sums away a label still has to match and read every series it sums, so a high series count is a query cost even when the result has one line. - **Measuring in a development environment.** One process, one host, one environment collapses three of the multipliers to 1 and hides the real figure. ## What to actually do with this Before adding a label, ask three questions in order: 1. **What is this label's ceiling** — not how many values exist today, but how many it can take? 2. **What is it multiplied by** — the other labels already on the metric, and the per-instance labels the collection tier will attach? 3. **Will anyone ever filter or group by it?** A label nobody queries pays the full multiplication and returns nothing for it. The third question prunes more labels in practice than the other two combined. Teams add labels because the value happened to be in scope at the call site, not because a query needs it — and the store charges the product either way.

  • The product of a metric's label values is 12,000 but the store reports 900 series. What explains the gap, and can you rely on it?
    Real label sets are sparse: only combinations that actually occur become series, and most label pairs are correlated — a door exists at one site, a tier only appears on certain routes. You can note the gap, but you cannot rely on it. Sparsity is a property of current traffic, so it shrinks a product of bounded factors and does nothing about a factor that grows with traffic.
  • What happens to existing dashboards when you add a new label to a metric that is already in production?
    Every existing series stops receiving samples and a new set of series begins, because identity changed. A range query spanning the deploy sees one set end and another start rather than a continuous line. Queries that aggregate the label away recover once the range is entirely on one side; anything pinned to an exact label set, including recorded aggregates and alert rules, has to be updated.

The label set is a compound primary key: the store does not keep one row per metric, it keeps one row per distinct combination of key columns.

saying these in an interview costs you the question

  • Says adding a label adds one series rather than multiplying
  • Thinks the metric name alone identifies what is stored
  • Treats two label values as variants of a single series
  • Ignores the per-instance labels the collection tier attaches
  • Counts label keys instead of the product of their values