Prometheus Cardinality Estimator: Forecast Series & Cost

Forecast Prometheus time-series count and managed-vendor cost before they explode.

For each label, enter how many unique values it produces. status typically has ~10 values, a path template ~50-200, user_id can be millions.

Total Time Series

0

Per replica: 0

Risk: low

Estimated cost / month: $0.00

Cardinality: The #1 Reason Prometheus Bills Explode

Every unique combination of label values on a metric creates a separate time series. Multiply the cardinalities of every label, then multiply by the number of replicas emitting that metric — that's your total series count for the metric. Get this wrong and a single metric can produce millions of series, crashing Prometheus or racking up thousands per month on managed observability platforms.

Labels That Should NEVER Exist on Metrics

  • user_id — unbounded, grows with your user count
  • request_id / trace_id — unique per request, infinite cardinality
  • session_id, order_id, email — same problem
  • ip / client_ip — millions of possible values
  • Raw URL path with IDs — use route templates instead (e.g. /users/:id)
  • Timestamps as labels — never

Safe Cardinality Targets

Per metricStatusAction
< 1,000HealthyNone
1K-10KWatchNote in dashboards
10K-100KRiskAudit labels
100K-1MHighDrop high-card labels via relabel_config
> 1MCriticalDrop the metric or relabel immediately

Finding Your Worst Offenders

Run this PromQL in your environment to find the highest-cardinality metrics:

topk(20, count by(__name__) ({__name__=~".+"}))

To find the worst label per metric:

topk(20, count by(__name__, label_name) ({__name__=~".+"}))

See the Metrics & Observability Guide for the full optimization playbook.

Cardinality killing your bill?

Recon profiles your real Prometheus cardinality across services and flags the worst offenders.

Join the waitlist →