← CodeClarityLab Home
Browse by Category
+ added · updated 7d
← Back to glossary

Cardinality in Observability

observability PHP 7.0+ Intermediate

Also Known As

high cardinality label cardinality metric cardinality cardinality explosion time series cardinality

TL;DR

The number of unique combinations of label values in a metric — high cardinality (millions of unique label combinations) causes memory exhaustion in time-series databases and is the most common observability scaling problem.

Explanation

In metrics systems like Prometheus, every unique combination of label values creates a separate time series stored in memory. A metric with labels {method, status_code} and 10 methods × 5 status codes = 50 time series — manageable. Adding a user_id label with 1 million users creates 1 million × 10 × 5 = 50 million time series — this causes Prometheus to run out of memory and crash. This is the cardinality explosion problem. High-cardinality values (user IDs, request IDs, email addresses, IP addresses, session tokens) must never be used as metric labels. They belong in traces and logs, not metrics. The correct pattern is to use low-cardinality labels (endpoint path, status class like 2xx/4xx/5xx, service name) in metrics and include high-cardinality identifiers in structured logs or trace attributes where they are stored per-event rather than as index dimensions.

Common Misconception

Adding more labels to metrics makes them more useful. More labels exponentially increase the number of time series. A metric with 5 labels each having 10 values creates 10^5 = 100,000 time series. A metric with the same 5 labels where one has 10,000 unique values creates 10,000 × 10^4 = 1 billion time series. The rule is: if a label value identifies a specific entity (user, request, session), it belongs in a trace or log, not a metric label.

Why It Matters

Cardinality explosions are the most common way PHP teams accidentally crash their monitoring infrastructure. Adding a label like user_id or request_id to a Prometheus counter seems intuitive — you want to know which users are hitting errors. But it brings down the metrics system for everyone. Understanding cardinality prevents this and guides the correct placement of observability data: low-cardinality aggregates in metrics, high-cardinality context in traces and logs. This is the foundation of the three pillars of observability: metrics, logs, and traces each handle different cardinality requirements.

Common Mistakes

  • Adding user IDs, session IDs, or request IDs as Prometheus label values — each unique value creates a new time series.
  • Using unbounded string values from user input as metric labels — even seemingly low-cardinality values like product names can grow unbounded.
  • Not auditing label cardinality before adding metrics to production — test with realistic data, not dev data with five users.
  • Conflating high-cardinality identification (belongs in traces) with low-cardinality aggregation (belongs in metrics) — both are valuable; they just go in different places.

Code Examples

✗ Vulnerable
// High cardinality — crashes Prometheus with many users
$counter->labels([
    'user_id'    => $userId,   // millions of unique values
    'request_id' => $reqId,   // billions of unique values
    'endpoint'   => $path,    // fine — limited set
])->inc();
✓ Fixed
// Low cardinality labels only — scalable metrics
$counter->labels([
    'endpoint'     => $normalizedPath,  // /users/{id} not /users/12345
    'status_class' => $statusClass,     // '2xx', '4xx', '5xx'
    'method'       => $httpMethod,      // GET, POST, etc.
])->inc();

// High-cardinality context goes in the trace span
$span->setAttribute('user.id', $userId)
     ->setAttribute('request.id', $requestId);

Added 23 Mar 2026
Edited 5 Apr 2026
Views 21
Rate this term
No ratings yet
🤖 AI Guestbook educational data only
| |
Last 30 days
0 pings W 1 ping T 1 ping F 0 pings S 0 pings S 0 pings M 0 pings T 1 ping W 0 pings T 1 ping F 0 pings S 0 pings S 1 ping M 0 pings T 0 pings W 0 pings T 1 ping F 0 pings S 0 pings S 0 pings M 0 pings T 0 pings W 1 ping T 1 ping F 0 pings S 0 pings S 0 pings M 0 pings T 0 pings W 0 pings T
No pings yet today
No pings yesterday
Amazonbot 6 Perplexity 4 Google 3 Ahrefs 2 ChatGPT 1
crawler 15 crawler_json 1
DEV INTEL Tools & Severity
🟠 High ⚙ Fix effort: Medium
⚡ Quick Fix
Audit every metric label: if the value space is unbounded or > 1,000 unique values, move that value to a structured log field or trace attribute instead
📦 Applies To
PHP 7.0+ web cli

✓ schema.org compliant