Upcoming Webinar:

Getting Started with OpenObserve

July 16, 2026
11:00 AM ET

What is High Cardinality in Observability?

High cardinality means a field or metric label has a very large number of unique values — user IDs, container IDs, request IDs — which can explode storage and query costs in many observability systems.

Metrics & Monitoring

High cardinality describes a field, label, or dimension with a very large number of unique values. In observability, cardinality is the count of distinct time series or distinct field values a system must track — and it is the single most common reason metrics systems fall over or observability bills explode.

Low vs high cardinality

FieldUnique valuesCardinality
HTTP method~9Low
Status code~60Low
Kubernetes pod namethousands, churningHigh
User IDmillionsVery high
Request/trace IDunboundedExtreme

Cardinality multiplies across labels: endpoint (100) × region (20) × status (60) is already 120,000 series from three innocent-looking labels.

Why high cardinality hurts

Time-series databases like Prometheus create a separate series (with memory-resident index entries) for every unique label combination. As unique combinations grow, memory usage balloons, queries slow, and ingestion stalls — the notorious “cardinality explosion.” See Prometheus data cardinality for the mechanics. Some commercial platforms turn the same problem into pricing: charging per custom-metric series makes per-customer labels financially, rather than technically, impossible.

The tension is that high-cardinality questions are the valuable ones: which tenant, which device, which deployment caused the regression. Aggregated dashboards can’t answer them.

Managing cardinality

  • Keep unbounded values (user IDs, request IDs) out of metric labels; put them in logs and traces instead, where they belong
  • Aggregate or drop labels you never query, at collection time
  • Use recording rules / streaming aggregation for dashboard queries
  • Choose storage engines that tolerate cardinality: columnar formats index nothing by default, so a high-cardinality field costs the same as any other column

High cardinality in OpenObserve

OpenObserve stores telemetry as columnar Parquet rather than per-series indexes, so high-cardinality fields in logs, metrics, and traces don’t cause memory explosions or per-series charges — you can keep user IDs and pod names queryable without redesigning your schema around the backend’s limits.

Frequently asked questions

What is an example of high cardinality?

A metric labeled by HTTP status code has ~60 possible values — low cardinality. The same metric labeled by user ID in a system with 10 million users has 10 million possible values — high cardinality. Combined labels multiply, so user_id × endpoint × region can produce billions of unique series.

Why is high cardinality a problem for Prometheus?

Prometheus keeps an in-memory entry and a separate time series for every unique label combination. Millions of series inflate memory, slow queries, and can crash the server. This is why per-user or per-request labels are considered an anti-pattern in Prometheus.

Is high cardinality always bad?

No — high-cardinality data is exactly what you need to answer questions like "which customer is affected?". The problem is architectural — systems that index every label combination pay dearly for it, while columnar storage engines handle high-cardinality fields much more economically.

Related terms

Keep reading

See these concepts in action

OpenObserve unifies logs, metrics, traces, and frontend monitoring in one open-source platform — at a fraction of the cost of legacy tools.

Book a DemoBook a Demo