Safeguard
Developer Tools•

Metric label cardinality: what never to use as a label

Every unique label combination creates a new time series. Learn what to keep out of metric labels, where that detail belongs, and how to spot a runaway.

Safeguard Security Team
3 min read

Never use values with many possibilities, such as user IDs, email addresses or request IDs, as metric labels. Each distinct combination of label values creates a new time series, so one careless label can multiply storage and slow every query. Put that detail in logs or traces instead.

What cardinality means

In a metrics system with labels, a metric name plus a set of label values identifies one series. Add a route label with 20 values and a status label with 5, and you have up to 100 series for that metric. Add a user label with 50,000 values, and you now have up to five million.

The Prometheus naming guidance states it directly: do not use labels to store dimensions with high cardinality, such as user IDs or email addresses. It also notes that each distinct combination creates a new series, so labels can greatly increase the data you store.

Safe and unsafe labels

Usually fine, because the set of values is small and known:

  • route group or handler name
  • HTTP method
  • status class, such as 2xx or 5xx
  • region or environment
  • job or service name

Usually unsafe, because the set is unbounded:

  • user, tenant or session ID in a large system
  • request ID or trace ID
  • full URL with query strings
  • raw error messages
  • IP addresses

Be careful with route labels too. If you label by the raw path, a URL such as /orders/48213 produces one series per order. Label by the route template, /orders/:id, instead.

Where the detail goes

You still want to know which tenant is having trouble. Use the right signal:

  • logs hold per request fields, searchable by tenant or user
  • traces hold the path and timing of individual requests
  • metrics hold aggregates, with a small number of labels

If one tenant matters a great deal, a separate metric for a handful of named tenants is better than a label that includes all of them.

How to spot a runaway

Watch the count of active series per metric, and alert when it grows faster than usual. After each release, compare series counts for new metrics. The usual cause is a new label fed by a variable like a path or error string.

Put a cap in front of it

Many client libraries and collectors let you limit label values or drop labels at ingestion. A limit is a safety net, not a design. Review new metrics in code review with one question: what is the largest number of values each label can take?

Quick check

Is a tenant label ever fine?

If you have a few dozen tenants and the count is stable, it can be. With thousands, put tenant in logs.

Do histograms add cardinality?

Yes, since each bucket is its own series. Choose buckets with care and keep other labels few.

Sources

Last reviewed: 19 October 2026.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.

Self-healing security runs on Safeguard.

Your first fix PR is minutes away.

No sales call required, even your agent can complete the purchase over MCP.