Free — no signup required

Mitigation Strategy 1 — Remove the Label

2 min read

Fix It at the Source (Preferred)

The cleanest fix is to remove the high-cardinality label from the instrumentation code. This requires a code change, but it eliminates the problem permanently.

Bad instrumentation (Python example):

# This creates one series per user — catastrophic at scale
http_requests_counter.labels(
    method="GET",
    status_code=200,
    user_id=request.user.id   # ← HIGH CARDINALITY
).inc()

Good instrumentation:

# Track what matters at the metric level; use logs/traces for per-user data
http_requests_counter.labels(
    method="GET",
    status_code=200,
    region=request.headers.get("X-Region", "unknown")  # ← LOW CARDINALITY
).inc()

The rule of thumb: if a label value could be unique per request, it doesn't belong on a metric. Per-request data belongs in logs (structured) or traces (distributed). Metrics are for aggregated, population-level signals.

Fix It at the Collector (When You Can't Change the Code)

If the high-cardinality label comes from a third-party library, a vendor agent, or a service you don't control, you can strip the label in your OpenTelemetry Collector before it reaches the database.

The attributes processor with action: delete removes a label key from every data point passing through the pipeline — listing user_id, client_ip, and trace_id as keys to delete strips all three from every metric that passes through.

What happens to the data: When Prometheus receives http_requests_total{method="GET", status_code="200"} (without user_id), all the requests that previously created separate per-user series now merge into a single series. You lose the per-user breakdown in metrics (which you shouldn't have had there anyway), but the total counts remain accurate.

The metricstransform processor offers more surgical control — you can rename labels, merge label values, or apply regex transformations — but for simple deletion, attributes is sufficient.

Prometheus metric_relabel_configs (Drop at Scrape Time)

If you're scraping a target directly with Prometheus (no OTel Collector in the path), you can drop labels using relabeling rules in your scrape config — a metric_relabel_configs entry with a labeldrop action and a regex matching user_id|client_ip|trace_id strips all three from every scraped series.

This runs after scraping but before storage — the label is dropped before any series are written to the TSDB.

This is one of 18 chapters

Every chapter is free — Kubernetes, Terraform, SRE, distributed systems, and more — with fast daily review built in.

Sign up free