---
title: "Use dynamic labels sparingly | Grafana Labs"
description: "Three conditions a dynamic label must meet, and filter expressions as the alternative"
---

> For a curated documentation index, see [llms.txt](/llms.txt). For the complete documentation index, see [llms-full.txt](/llms-full.txt).

## Use dynamic labels sparingly

A **dynamic label** is a label whose value is extracted from a log line’s content at ingestion or query time, which means the label values can vary. This variance can cause a single stream to split into many streams instead of being fixed, or static. For example, if your app writes `level=error` into each log line, promoting that value to a `level` label makes it dynamic. Turning an HTTP status class like `2xx` or `5xx` from access logs into a label is another common case. Use dynamic labels rarely, and only when all of the following are true:

- The value set is low-cardinality, ideally tens of values.
- The values are long lived, such as the first segment of an HTTP path, not ephemeral IDs.
- Users actually query by the label frequently.

Otherwise, don’t index it. Loki’s **filter expressions**, which search log content at query time, are fast. `{app="api"} |= "level=error"` performs comparably to a `level` label for many workloads, without splitting your streams. Don’t add a label until you know you need it.
