Zenaique

Fill in the failure mode high cardinality attributes cause in trace indexes

Fill in blank·Easy·4.0 · 0·~1 min·Asked atElasticJpmorganStability Ai
Attempt it
Storing a high cardinality value like user email or full prompt text as an indexed span attribute blows up the size and slows down trace queries.
TL;DR

High-cardinality indexed attributes (email, full prompt text) make the trace index bloat in proportion to cardinality and slow down trace search and filter queries.

Memory aid
Sign in to see the mnemonic that makes this stick.
Easy to grasp

Imagine a phone book where every entry has a unique tag. If the tags are useful categories like 'restaurant' or 'plumber', the index at the back is small because many entries share each tag. But if the tag is the person's full email address, every entry has its own tag and the index is as long as the phone book itself, plus you pay double the storage. Looking up 'all entries tagged restaurant' is fast; looking up 'all entries tagged some very unique string' is slow because you have to scan a huge index just to find the few matches. Trace storage works the same way: a span attribute that takes a different value on almost every span is bad to index. Store it as data on the span, just do not index it.

Concept explanation~2 min read

Everything you need to truly understand this topic: intuition, mechanics, step by step explanation, code, formulas, and worked example. Click to expand.

Span attributes are how you make traces queryable. The backend builds indexes on them so you can ask 'show me all spans where model = claude-sonnet and latency > 5s'. Index design is invisible to most engineers until the trace backend bill spikes or queries get slow, and then it becomes the most important property of the instrumentation.

This section covers why cardinality is the dominant factor in index cost, the practical rule of thumb for deciding what to index, the multi-tier instrumentation pattern that recovers query power on high-cardinality fields, and the backend-specific nuances.

Why cardinality is the dominant cost

Most trace backends use an inverted index. The index is a map from each distinct value of an attribute to the list of spans carrying that value. Storage scales with the number of distinct values.

A small example

Suppose 1 million spans, all with attribute model. If model has 20 distinct values, the index has 20 entries, each pointing to ~50,000 spans. Index size is roughly 20 * (string + posting list) = small.

If you also index user_email and there are 200,000 distinct emails across the spans, the index has 200,000 entries, each pointing to ~5 spans. Index size is 200,000 * (string + posting list). For typical email lengths, this is often as big as or bigger than the underlying span data.

Query latency

Low-cardinality lookup (model = 'claude-sonnet'): scan one short posting list, return ~50,000 spans. Fast.

High-cardinality range lookup (user_email LIKE 'alice%'): scan thousands of index entries to find matches, return a few spans per match. Slow. The query planner often falls back to scanning the data rather than the index, which is even slower.

The implication

Index what you filter or group by frequently and what has manageable cardinality. Store everything else as payload.

The 100-1000-10000 rule of thumb
Multi-tier instrumentation: coarsened companions
Backend-specific nuances
Sign in to unlock the full deep dive.

Situations where this technique stops working.

Sign in to see when this approach fails.

2–4 min · Everything important, quickly.

Sign in to see the quick scan of the deep dive.
AttributeCardinalityIndex or payload?
modelLow (~20)Indexed
environment, prod or stagingLow (3-5)Indexed
release_tag or git_shaMedium (100-1000)Indexed (rotates over time)
prompt_template_idMedium (100-1000)Indexed
userId (hashed)HighIndexed only if you filter by it
user_emailVery highPayload (and consider GDPR)
full prompt textVery highPayload
full response textVery highPayload

Real products, models, and research that use this idea.

  • Datadog APM's pricing and the Honeycomb pricing model both penalize high-cardinality indexed dimensions explicitly, making the cost visible upfront.
  • Langfuse and Arize Phoenix backends store full prompt and completion text as un-indexed payload; the indexed fields are model, latency, cost, and tags.
Sign in to see more production examples.

What an interviewer would ask next. Try answering before peeking at the approach.

QHow do you find which attributes are blowing up the index in an existing system?
A

Most backends expose cardinality estimates per attribute; pull the top 20 by cardinality and audit. Datadog has a per-tag cardinality dashboard; Elasticsearch-based backends expose terms aggregations.

2 more follow-ups an interviewer would ask next. Sign in to reveal them.

Red flags & common mistakes

The phrases that signal junior thinking. Click to expand.

Most common mistake

Defaulting every span attribute to indexed (because the SDK does not distinguish), then blowing up the trace backend storage cost and discovering it during an incident.

Sign in to see all red flags and common mistakes.

60 second bullets to scan on the way to the call.

  • Why inverted indexes scale with cardinality of indexed values

  • The two costs of indexing high-cardinality fields (storage, query latency)

Sign in to unlock the revision sheet.

Primary sources. Browse if you want the original framing.

Similar questions

Same topic, related formats. Practice these next.

4 curated
Next question
Describe how end user thumbs up/down should flow back onto a trace
Flashcard·Easy