Glossary
Glossary

What Is Cardinality in Metrics?

By Sazabi Team

Last verified on Nov 8, 2026.

Cardinality is the number of distinct values in a set. For metrics, it is the number of unique combinations of label values a metric has. In Prometheus each combination is a separate time series, so a metric's cardinality is the number of series it creates. The Prometheus data model says that changing any label value, including adding or removing labels, creates a new time series.

Why Labels Multiply

Labels are what let one metric name describe many things. They also multiply. The count of series for a metric is, at most, the product of the number of values in each label.

http_requests_total{method="GET", status="200", route="/checkout"}

Say method has 5 values, status has 5, and route has 40. That is 5 * 5 * 40 = 1,000 series, which is fine. Add a user_id label with 10,000 users and it becomes 1,000 * 10,000 = 10,000,000 series. Nothing about the metric changed except one label.

Prometheus's instrumentation guide gives a real-world version. A node_exporter filesystem metric produces tens of series per node, so 10,000 nodes give roughly 100,000 series, which is fine. Adding a quota per user would reach a double-digit number of millions with 10,000 users on 10,000 nodes, which is too much for Prometheus. Even with smaller numbers, it notes an opportunity cost: you cannot store other, potentially more useful metrics on that machine.

What Not to Put in a Label

Prometheus's naming guide is explicit. Do not use labels to store dimensions with many different values, such as user IDs, email addresses, or other unbounded sets of values. Common offenders:

  • User, session, request, and trace IDs
  • Full URLs with query strings, instead of a route name
  • Raw error messages
  • Container or pod names that change on every deploy

Use the bounded version instead: route instead of URL, error class instead of message. The unique detail belongs in a log line or a trace ID on a span.

Rules of Thumb From Prometheus

The instrumentation guidance is to try to keep the cardinality of your metrics below 10. For metrics that exceed that, aim to limit them to a handful across your whole system, and note that the vast majority of metrics should have no labels. If a metric has a cardinality over 100 or could grow that large, look at reducing dimensions or moving the analysis away from monitoring to a general-purpose processing system. If you are unsure, start with no labels and add them as use cases arise.

Guardrails

  • OpenTelemetry SDK limit. The specification defines cardinality as the number of unique attribute combinations, and says SDKs should support a cardinality limit, with a default of 2000. Measurements past the limit are folded into a single data point with the attribute otel.metric.overflow=true rather than dropped or double-counted.
  • Vector. The tag_cardinality_limit transform limits tag cardinality on metric events. By default it drops the tag when the limit would be exceeded. Vector's docs call it a protection against accidental cardinality problems that can disrupt metric storage, and note it is mainly useful on incremental counters.
  • Review labels at write time. Ask what the largest possible set of values is. If the answer is "as many as our users," it is not a label.

Cardinality in Logs and Metrics

The same word applies to log fields, but the cost is different. A log record is stored once whether a field is unique or not, so a request ID is cheap in a log and ruinous as a metric label. See structured logging for what to put in a record.

To find out when a metric or field suddenly starts producing far more distinct values than before, see cardinality jumps, which covers detecting high cardinality in production. Related reading: cost anomalies and field drift.

Metrics in Sazabi

Sazabi is an AI-native observability and security platform. Sazabi ingests OpenTelemetry metrics (Prometheus metrics through an OpenTelemetry Collector) and OTLP traces through the same intake as your logs. It stores each metric data point and each span as a log record that its agent queries alongside your logs, so there is no separate metrics store to run. Each incoming metric data point becomes a log record with its labels preserved as attributes, so you can search metrics next to your logs. See the OpenTelemetry metrics integration and the Prometheus integration.

Frequently Asked Questions

What is cardinality in metrics?

It is the number of unique combinations of label values a metric has. In Prometheus each unique combination is its own time series, so cardinality is also the series count for that metric.

What causes cardinality to explode?

Putting an unbounded value in a label, such as a user ID, email address, request ID, or full URL. Each new value creates a new time series, and labels multiply across each other.

What is a safe number of label values?

Prometheus guidance is to keep a metric below a cardinality of 10 where you can, and to look for another approach when it is over 100 or could grow that large.

Is cardinality a problem in logs too?

Much less. A log line is one record regardless of how unique its fields are, so request IDs and user IDs belong in logs. The cost problem is specific to metrics, where every combination is stored as a series.

Sources

  1. A time series is identified by metric name and labels; changing any label value, or adding or removing labels, creates a new time series (accessed Nov 8, 2026)
  2. Every unique combination of key-value label pairs is a new time series; do not use labels for dimensions such as user IDs or email addresses (accessed Nov 8, 2026)
  3. Guideline to keep metric cardinality below 10; investigate alternatives above 100; node_exporter quota per user example; most metrics should have no labels (accessed Nov 8, 2026)
  4. The number of unique attribute combinations is cardinality; SDKs should support a cardinality limit, default 2000, with an otel.metric.overflow attribute for the excess (accessed Nov 8, 2026)
  5. Vector tag_cardinality_limit transform limits tag cardinality on metric events and by default drops the tag when the limit would be exceeded (accessed Nov 8, 2026)
  6. Sazabi stores each metric data point as a log record with its labels preserved as attributes (accessed Nov 8, 2026)