Skip to main content
Metric tags with unbounded or highly variable values. User IDs, request IDs, timestamps, IP addresses as tags. Each unique value creates a new time series, and your metric storage explodes. user_id on a latency metric seems useful. You could see latency per user. But you have a million users. Now you have a million time series for one metric. Metrics are meant to be aggregated. Tags with high cardinality defeat the purpose.

Example

A request latency metric with user_id as a tag:
http_request_duration_seconds{service="api", endpoint="/users", user_id="usr_abc123"} 0.045
http_request_duration_seconds{service="api", endpoint="/users", user_id="usr_def456"} 0.052
http_request_duration_seconds{service="api", endpoint="/users", user_id="usr_ghi789"} 0.038
One metric × one endpoint × one million users = one million time series.
id: remove-user-id-tag
name: Remove user_id tag from metrics
description: Drop high-cardinality user_id tag. Creates millions of sparse time series.
metric:
  match:
    - tag: user_id
      exists: true
  transform:
    remove_tags:
      - user_id
Common high-cardinality tags: user_id, request_id, session_id, trace_id, ip_address, url (with query params), error_message. The test: could this tag have thousands or millions of unique values?

Enforce at edge

Strip the tag before metrics reach your provider.

Open PRs

Remove the tag from instrumentation code.
The best fix is removing the tag from instrumentation. If that’s not possible quickly, strip it at the edge to stop the bleeding while you fix the code.

How it works

Tero analyzes tag cardinality across your metrics. Tags with thousands or more unique values are flagged. Tero also checks whether these tags are used in queries or dashboards. A tag with 100,000 unique values that nobody filters by is a clear candidate for removal.