What cardinality measures
Cardinality is a count of how many different values a dimension can take. Device category has very few, a short and fixed list. Country has more but is still a bounded set. Page path on a large site has many. A dimension carrying a unique identifier for every visitor has as many values as there are visitors, which is as high as cardinality gets.
Analytics tools store pre-aggregated tables so that reports load quickly, and those tables have a limit on how many rows they can hold. When a dimension exceeds that limit, the rarest values stop receiving their own row and are combined into a single catch-all, usually labelled “(other)”.
Why cardinality matters
Because the values that disappear are usually the ones you were looking for. A high-cardinality dimension pushes the long tail into the catch-all row, and the long tail is where new keywords, unusual product variants and unexpected landing pages live — the things you did not already know about.
It also affects totals in a way that surprises people. A report grouped by a high-cardinality dimension can add up to less than the same metric shown without any breakdown, because the grouping itself has consumed the available row budget.
Where cardinality goes wrong
The classic mistake is sending an identifier as a custom dimension: an order number, a session identifier, a full URL including its query string, a timestamp. Each of those creates a new value on almost every event and exhausts the row budget immediately.
Untidy values do the same damage more slowly. URLs differing only by a tracking parameter, campaign names typed differently by different people, and product names with inconsistent spelling all inflate the count of distinct values without adding a single piece of information. Consistent UTM parameters prevent much of that.
The third is discovering it late. Nothing warns you at setup. The catch-all row simply grows until somebody notices that a report has stopped being useful and cannot say when it happened.
How to act on it
Before creating a custom dimension, ask how many distinct values it will ever hold. If the answer is one per visitor or one per order, it does not belong in a reporting dimension; it belongs in an exported dataset or your CRM, where row limits do not bite in the same way.
Group values instead of storing them raw. Product category rather than product name, price band rather than price, page template rather than full URL. You can always keep the raw value in a warehouse for the rare analysis that genuinely needs it.
Then tidy what you already send: strip unnecessary query parameters from page paths, and agree campaign naming once so a single campaign is not counted as several. If a report is already dominated by the catch-all row, shortening the date range often restores detail, because fewer distinct values appear in a shorter window. Where this keeps recurring, the fix belongs in the GA4 configuration rather than in the report.