# Datadog custom metrics cost: tag cardinality is the trap

Custom metrics are not billed per metric name. They are billed per **unique combination of metric name and tag values**. One metric name with a `user_id` tag and 50k users is 50k billable custom metrics. This is the most expensive line item teams discover by surprise.

## The counting rule (from the docs)

The docs example: `request.latency` submitted from host:A and host:B, tagged `endpoint:X/Y` and `status:200/400`, counts as **four** custom metrics, one per unique tag-value combination actually submitted. Add a finer tag and the count scales with the most granular tag: their temperature example shows adding `city` (3 values) multiplying the count, while a coarser tag on top adds nothing.

So: the bill follows your highest-cardinality tag. `status` (4 values) is free-ish. `user_id`, `request_id`, `container_id` are invoice events.

## Guardrails

1. **Never tag by unbounded IDs.** user_id, email, session_id, request_id, IP: aggregate these or drop the tag, keep the value in the log event instead.
2. **Estimate before shipping.** List the distinct values of each tag key you plan to use. Multiply. That is roughly your new custom metric count for that name.
3. **Watch the Usage page.** It shows custom metric volumes over time; a hockey stick right after a deploy names the culprit metric.
4. **Metrics without Limits.** If you are on it, you get ingested vs indexed volumes and can drop indexing on high-cardinality tags you only need for short-term debugging. Learn the difference before you need it.
5. **DogStatsD histograms vs distributions.** Distributions aggregate server-side and can carry more tag combos cheaply-ish; know which one you are emitting.

## The agent-side fix

When you find the offending tag: remove it at emission (client code), or use the agent/metrics filtering to drop the tag before submission. Fixing it in dashboards does nothing, the series are already billed at ingest.