<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Understand labels on Grafana Labs</title><link>https://grafana.com/docs/loki/v3.0.x/get-started/labels/</link><description>Recent content in Understand labels on Grafana Labs</description><generator>Hugo -- gohugo.io</generator><language>en</language><atom:link href="/docs/loki/v3.0.x/get-started/labels/index.xml" rel="self" type="application/rss+xml"/><item><title>Label best practices</title><link>https://grafana.com/docs/loki/v3.0.x/get-started/labels/bp-labels/</link><pubDate>Fri, 06 Mar 2026 07:23:54 +0000</pubDate><guid>https://grafana.com/docs/loki/v3.0.x/get-started/labels/bp-labels/</guid><content><![CDATA[&lt;h1 id=&#34;label-best-practices&#34;&gt;Label best practices&lt;/h1&gt;
&lt;p&gt;Grafana Loki is under active development, and we are constantly working to improve performance. But here are some of the most current best practices for labels that will give you the best experience with Loki.&lt;/p&gt;
&lt;h2 id=&#34;static-labels-are-good&#34;&gt;Static labels are good&lt;/h2&gt;
&lt;p&gt;Use labels for things like regions, clusters, servers, applications, namespaces, and environments. They will be fixed for a given system/app and have bounded values. Use static labels to make it easier to query your logs in a logical sense (for example, show me all the logs for a given application and specific environment, or show me all the logs for all the apps on a specific host).&lt;/p&gt;
&lt;h2 id=&#34;use-dynamic-labels-sparingly&#34;&gt;Use dynamic labels sparingly&lt;/h2&gt;
&lt;p&gt;Too many label value combinations leads to too many streams. The penalties for that in Loki are a large index and small chunks in the store, which in turn can actually reduce performance.&lt;/p&gt;
&lt;p&gt;To avoid those issues, don&amp;rsquo;t add a label for something until you know you need it! Use filter expressions (&lt;code&gt;|= &amp;quot;text&amp;quot;&lt;/code&gt;, &lt;code&gt;|~ &amp;quot;regex&amp;quot;&lt;/code&gt;, …) and brute force those logs. It works &amp;ndash; and it&amp;rsquo;s fast.&lt;/p&gt;
&lt;p&gt;If you often parse a label from a log line at query time, the label has a high cardinality, and extracting that label is expensive in terms of performance; consider extracting the label on the client side
attaching it as &lt;a href=&#34;/docs/loki/v3.0.x/get-started/labels/structured-metadata/&#34;&gt;structured metadata&lt;/a&gt; to log lines .&lt;/p&gt;
&lt;p&gt;From early on, we have set a label dynamically using Promtail pipelines for &lt;code&gt;level&lt;/code&gt;. This seemed intuitive for us as we often wanted to only show logs for &lt;code&gt;level=&amp;quot;error&amp;quot;&lt;/code&gt;; however, we are re-evaluating this now as writing a query. &lt;code&gt;{app=&amp;quot;loki&amp;quot;} |= &amp;quot;level=error&amp;quot;&lt;/code&gt; is proving to be just as fast for many of our applications as &lt;code&gt;{app=&amp;quot;loki&amp;quot;,level=&amp;quot;error&amp;quot;}&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;This may seem surprising, but if applications have medium to low volume, that label causes one application&amp;rsquo;s logs to be split into up to five streams, which means 5x chunks being stored.  And loading chunks has an overhead associated with it. Imagine now if that query were &lt;code&gt;{app=&amp;quot;loki&amp;quot;,level!=&amp;quot;debug&amp;quot;}&lt;/code&gt;. That would have to load &lt;strong&gt;way&lt;/strong&gt; more chunks than &lt;code&gt;{app=&amp;quot;loki&amp;quot;} != &amp;quot;level=debug&amp;quot;&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Above, we mentioned not to add labels until you &lt;em&gt;need&lt;/em&gt; them, so when would you &lt;em&gt;need&lt;/em&gt; labels?? A little farther down is a section on &lt;code&gt;chunk_target_size&lt;/code&gt;. If you set this to 1MB (which is reasonable), this will try to cut chunks at 1MB compressed size, which is about 5MB-ish of uncompressed logs (might be as much as 10MB depending on compression). If your logs have sufficient volume to write 5MB in less time than &lt;code&gt;max_chunk_age&lt;/code&gt;, or &lt;strong&gt;many&lt;/strong&gt; chunks in that timeframe, you might want to consider splitting it into separate streams with a dynamic label.&lt;/p&gt;
&lt;p&gt;What you want to avoid is splitting a log file into streams, which result in chunks getting flushed because the stream is idle or hits the max age before being full. As of &lt;a href=&#34;/blog/2020/04/01/loki-v1.4.0-released-with-query-statistics-and-up-to-300x-regex-optimization/&#34;&gt;Loki 1.4.0&lt;/a&gt;, there is a metric which can help you understand why chunks are flushed &lt;code&gt;sum by (reason) (rate(loki_ingester_chunks_flushed_total{cluster=&amp;quot;dev&amp;quot;}[1m]))&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;It’s not critical that every chunk be full when flushed, but it will improve many aspects of operation. As such, our current guidance here is to avoid dynamic labels as much as possible and instead favor filter expressions. For example, don’t add a &lt;code&gt;level&lt;/code&gt; dynamic label, just &lt;code&gt;|= &amp;quot;level=debug&amp;quot;&lt;/code&gt; instead.&lt;/p&gt;
&lt;p&gt;Here are some best practices for using dynamic labels with Loki:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Ensure the labels have low cardinality, ideally limited to tens of values.&lt;/li&gt;
&lt;li&gt;Use labels with long-lived values, such as the initial segment of an HTTP path: &lt;code&gt;/load&lt;/code&gt;, &lt;code&gt;/save&lt;/code&gt;, &lt;code&gt;/update&lt;/code&gt;.
&lt;ul&gt;
&lt;li&gt;Do not extract ephemeral values like a trace ID or an order ID into a label; the values should be static, not dynamic.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Only add labels that users will frequently use in their queries.
&lt;ul&gt;
&lt;li&gt;Don’t increase the size of the index and fragment your log streams if nobody is actually using these labels. This will degrade performance.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;label-values-must-always-be-bounded&#34;&gt;Label values must always be bounded&lt;/h2&gt;
&lt;p&gt;If you are dynamically setting labels, never use a label which can have unbounded or infinite values. This will always result in big problems for Loki.&lt;/p&gt;
&lt;p&gt;Try to keep values bounded to as small a set as possible. We don&amp;rsquo;t have perfect guidance as to what Loki can handle, but think single digits, or maybe 10’s of values for a dynamic label. This is less critical for static labels. For example, if you have 1,000 hosts in your environment it&amp;rsquo;s going to be just fine to have a host label with 1,000 values.&lt;/p&gt;
&lt;p&gt;As a general rule, you should try to keep any single tenant in Loki to less than &lt;strong&gt;100,000 active streams&lt;/strong&gt;, and less than a million streams in a 24-hour period.  These values are for HUGE tenants, sending more than &lt;strong&gt;10 TB&lt;/strong&gt; a day. If your tenant is 10x smaller, you should have at least 10x fewer labels.&lt;/p&gt;
&lt;h2 id=&#34;be-aware-of-dynamic-labels-applied-by-clients&#34;&gt;Be aware of dynamic labels applied by clients&lt;/h2&gt;
&lt;p&gt;Loki has several client options: &lt;a href=&#34;/docs/alloy/latest/&#34;&gt;Grafana Alloy&lt;/a&gt;, 
    &lt;a href=&#34;/docs/loki/v3.0.x/send-data/promtail/&#34;&gt;Promtail&lt;/a&gt; (which also supports systemd journal ingestion and TCP-based syslog ingestion), 
    &lt;a href=&#34;/docs/loki/v3.0.x/send-data/fluentd/&#34;&gt;Fluentd&lt;/a&gt;, 
    &lt;a href=&#34;/docs/loki/v3.0.x/send-data/fluentbit/&#34;&gt;Fluent Bit&lt;/a&gt;, a 
    &lt;a href=&#34;/docs/loki/v3.0.x/send-data/docker-driver/&#34;&gt;Docker plugin&lt;/a&gt;, and more.&lt;/p&gt;
&lt;p&gt;Each of these come with ways to configure what labels are applied to create log streams. But be aware of what dynamic labels might be applied.
Use the Loki series API to get an idea of what your log streams look like and see if there might be ways to reduce streams and cardinality.
Series information can be queried through the 
    &lt;a href=&#34;/docs/loki/v3.0.x/reference/loki-http-api/&#34;&gt;Series API&lt;/a&gt;, or you can use &lt;a href=&#34;/docs/loki/v3.0.x/query/&#34;&gt;logcli&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;In Loki 1.6.0 and newer the logcli series command added the &lt;code&gt;--analyze-labels&lt;/code&gt; flag specifically for debugging high cardinality labels:&lt;/p&gt;

&lt;div class=&#34;code-snippet code-snippet__mini&#34;&gt;&lt;div class=&#34;lang-toolbar__mini&#34;&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet code-snippet__border&#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-none&#34;&gt;Total Streams:  25017
Unique Labels:  8

Label Name  Unique Values  Found In Streams
requestId   24653          24979
logStream   1194           25016
logGroup    140            25016
accountId   13             25016
logger      1              25017
source      1              25016
transport   1              25017
format      1              25017&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;In this example you can see the &lt;code&gt;requestId&lt;/code&gt; label had a 24653 different values out of 24979 streams it was found in, this is bad!!&lt;/p&gt;
&lt;p&gt;This is a perfect example of something which should not be a label, &lt;code&gt;requestId&lt;/code&gt; should be removed as a label and instead
filter expressions should be used to query logs for a specific &lt;code&gt;requestId&lt;/code&gt;. For example if &lt;code&gt;requestId&lt;/code&gt; is found in
the log line as a key=value pair you could write a query like this: &lt;code&gt;{logGroup=&amp;quot;group1&amp;quot;} |= &amp;quot;requestId=32422355&amp;quot;&lt;/code&gt;&lt;/p&gt;
]]></content><description>&lt;h1 id="label-best-practices">Label best practices&lt;/h1>
&lt;p>Grafana Loki is under active development, and we are constantly working to improve performance. But here are some of the most current best practices for labels that will give you the best experience with Loki.&lt;/p></description></item><item><title>What is structured metadata</title><link>https://grafana.com/docs/loki/v3.0.x/get-started/labels/structured-metadata/</link><pubDate>Fri, 06 Mar 2026 07:23:54 +0000</pubDate><guid>https://grafana.com/docs/loki/v3.0.x/get-started/labels/structured-metadata/</guid><content><![CDATA[&lt;h1 id=&#34;what-is-structured-metadata&#34;&gt;What is structured metadata&lt;/h1&gt;


&lt;div class=&#34;admonition admonition-warning&#34;&gt;&lt;blockquote&gt;&lt;p class=&#34;title text-uppercase&#34;&gt;Warning&lt;/p&gt;&lt;p&gt;Structured metadata was added to chunk format V4 which is used if the schema version is greater or equal to &lt;code&gt;13&lt;/code&gt;. See 
    &lt;a href=&#34;/docs/loki/v3.0.x/configure/storage/#schema-config&#34;&gt;Schema Config&lt;/a&gt; for more details about schema versions.&lt;/p&gt;&lt;/blockquote&gt;&lt;/div&gt;

&lt;p&gt;Selecting proper, low cardinality labels is critical to operating and querying Loki effectively. Some metadata, especially infrastructure related metadata, can be difficult to embed in log lines, and is too high cardinality to effectively store as indexed labels (and therefore reducing performance of the index).&lt;/p&gt;
&lt;p&gt;Structured metadata is a way to attach metadata to logs without indexing them or including them in the log line content itself. Examples of useful metadata are
kubernetes pod names, process ID&amp;rsquo;s, or any other label that is often used in queries but has high cardinality and is expensive
to extract at query time.&lt;/p&gt;
&lt;p&gt;Structured metadata can also be used to query commonly needed metadata from log lines without needing to apply a parser at query time. Large json blobs or a poorly written query using complex regex patterns, for example, come with a high performance cost. Examples of useful metadata include container_IDs or user IDs.&lt;/p&gt;
&lt;h2 id=&#34;when-to-use-structured-metadata&#34;&gt;When to use structured metadata&lt;/h2&gt;
&lt;p&gt;You should only use structured metadata in the following situations:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;If you are ingesting data in OpenTelemetry format, using Grafana Alloy or an OpenTelemetry Collector. Structured metadata was designed to support native ingestion of OpenTelemetry data.&lt;/li&gt;
&lt;li&gt;If you have high cardinality metadata that should not be used as a label and does not exist in the log line.  Some examples might include &lt;code&gt;process_id&lt;/code&gt; or &lt;code&gt;thread_id&lt;/code&gt; or Kubernetes pod names.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;It is an antipattern to extract information that already exists in your log lines and put it into structured metadata.&lt;/p&gt;
&lt;h2 id=&#34;attaching-structured-metadata-to-log-lines&#34;&gt;Attaching structured metadata to log lines&lt;/h2&gt;
&lt;p&gt;You have the option to attach structured metadata to log lines in the push payload along with each log line and the timestamp.
For more information on how to push logs to Loki via the HTTP endpoint, refer to the 
    &lt;a href=&#34;/docs/loki/v3.0.x/reference/api/#ingest-logs&#34;&gt;HTTP API documentation&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Alternatively, you can use Grafana Alloy or Promtail to extract and attach structured metadata to your log lines.
See the 
    &lt;a href=&#34;/docs/loki/v3.0.x/send-data/promtail/stages/structured_metadata/&#34;&gt;Promtail: Structured metadata stage&lt;/a&gt; for more information.&lt;/p&gt;
&lt;p&gt;With Loki version 1.2.0, support for structured metadata has been added to the Logstash output plugin. For more information, see 
    &lt;a href=&#34;/docs/loki/v3.0.x/send-data/logstash/&#34;&gt;logstash&lt;/a&gt;.&lt;/p&gt;


&lt;div class=&#34;admonition admonition-warning&#34;&gt;&lt;blockquote&gt;&lt;p class=&#34;title text-uppercase&#34;&gt;Warning&lt;/p&gt;&lt;p&gt;Structured metadata size is taken into account while asserting ingestion rate limiting.
Along with that, there are separate limits on how much structured metadata can be attached per log line.&lt;/p&gt;

&lt;div class=&#34;code-snippet code-snippet__mini&#34;&gt;&lt;div class=&#34;lang-toolbar__mini&#34;&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet code-snippet__border&#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-none&#34;&gt;# Maximum size accepted for structured metadata per log line.
# CLI flag: -limits.max-structured-metadata-size
[max_structured_metadata_size: &amp;lt;int&amp;gt; | default = 64KB]

# Maximum number of structured metadata entries per log line.
# CLI flag: -limits.max-structured-metadata-entries-count
[max_structured_metadata_entries_count: &amp;lt;int&amp;gt; | default = 128]&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;&lt;/blockquote&gt;&lt;/div&gt;

&lt;h2 id=&#34;querying-structured-metadata&#34;&gt;Querying structured metadata&lt;/h2&gt;
&lt;p&gt;Structured metadata is extracted automatically for each returned log line and added to the labels returned for the query.
You can use labels of structured metadata to filter log line using a 
    &lt;a href=&#34;/docs/loki/v3.0.x/query/log_queries/#label-filter-expression&#34;&gt;label filter expression&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;For example, if you have a label &lt;code&gt;pod&lt;/code&gt; attached to some of your log lines as structured metadata, you can filter log lines using:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;logql&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-logql&#34;&gt;{job=&amp;#34;example&amp;#34;} | pod=&amp;#34;myservice-abc1234-56789&amp;#34;&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Of course, you can filter by multiple labels of structured metadata at the same time:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;logql&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-logql&#34;&gt;{job=&amp;#34;example&amp;#34;} | pod=&amp;#34;myservice-abc1234-56789&amp;#34; | trace_id=&amp;#34;0242ac120002&amp;#34;&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Note that since structured metadata is extracted automatically to the results labels, some metric queries might return an error like &lt;code&gt;maximum of series (50000) reached for a single query&lt;/code&gt;. You can use the 
    &lt;a href=&#34;/docs/loki/v3.0.x/query/log_queries/#keep-labels-expression&#34;&gt;Keep&lt;/a&gt; and 
    &lt;a href=&#34;/docs/loki/v3.0.x/query/log_queries/#drop-labels-expression&#34;&gt;Drop&lt;/a&gt; stages to filter out labels that you don&amp;rsquo;t need.
For example:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;logql&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-logql&#34;&gt;count_over_time({job=&amp;#34;example&amp;#34;} | trace_id=&amp;#34;0242ac120002&amp;#34; | keep job  [5m])&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
]]></content><description>&lt;h1 id="what-is-structured-metadata">What is structured metadata&lt;/h1>
&lt;div class="admonition admonition-warning">&lt;blockquote>&lt;p class="title text-uppercase">Warning&lt;/p>&lt;p>Structured metadata was added to chunk format V4 which is used if the schema version is greater or equal to &lt;code>13&lt;/code>. See
&lt;a href="/docs/loki/v3.0.x/configure/storage/#schema-config">Schema Config&lt;/a> for more details about schema versions.&lt;/p></description></item></channel></rss>