<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.7.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.7.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.7.x/get-started/labels/bp-labels/</link><pubDate>Thu, 09 Apr 2026 02:28:18 +0000</pubDate><guid>https://grafana.com/docs/loki/v3.7.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;../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 client 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; (which also supports systemd journal ingestion and TCP-based syslog ingestion), 
    &lt;a href=&#34;/docs/loki/v3.7.x/send-data/fluentd/&#34;&gt;Fluentd&lt;/a&gt;, 
    &lt;a href=&#34;/docs/loki/v3.7.x/send-data/fluentbit/&#34;&gt;Fluent Bit&lt;/a&gt;, a 
    &lt;a href=&#34;/docs/loki/v3.7.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.7.x/reference/loki-http-api/&#34;&gt;Series API&lt;/a&gt;, or you can use &lt;a href=&#34;../../../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>Cardinality</title><link>https://grafana.com/docs/loki/v3.7.x/get-started/labels/cardinality/</link><pubDate>Thu, 09 Apr 2026 02:28:18 +0000</pubDate><guid>https://grafana.com/docs/loki/v3.7.x/get-started/labels/cardinality/</guid><content><![CDATA[&lt;h1 id=&#34;cardinality&#34;&gt;Cardinality&lt;/h1&gt;
&lt;p&gt;The cardinality of a data attribute is the number of distinct values that the attribute can have.  For example, a boolean column in a database, which can only have a value of either &lt;code&gt;true&lt;/code&gt; or &lt;code&gt;false&lt;/code&gt; has a cardinality of 2.&lt;/p&gt;
&lt;p&gt;High cardinality refers to a column or row in a database that can have many possible values. For an online shopping system, fields like &lt;code&gt;userId&lt;/code&gt;, &lt;code&gt;shoppingCartId&lt;/code&gt;, and &lt;code&gt;orderId&lt;/code&gt; are often high-cardinality columns that can have hundreds of thousands of distinct values.&lt;/p&gt;
&lt;p&gt;Other examples of high cardinality attributes include the following:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Timestamp&lt;/li&gt;
&lt;li&gt;IP addresses&lt;/li&gt;
&lt;li&gt;Kubernetes pod names&lt;/li&gt;
&lt;li&gt;User ID&lt;/li&gt;
&lt;li&gt;Customer ID&lt;/li&gt;
&lt;li&gt;Trace ID&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;When we talk about &lt;em&gt;cardinality&lt;/em&gt; in Loki we are referring to the combination of labels and values and the number of log streams they create. In Loki, the fewer labels you use, the better. This is why Loki has a default limit of 15 index labels.&lt;/p&gt;
&lt;p&gt;High cardinality can result from using labels with a large range of possible values, &lt;strong&gt;or&lt;/strong&gt; combining many labels, even if they have a small and finite set of values, such as combining &lt;code&gt;status_code&lt;/code&gt; and &lt;code&gt;action&lt;/code&gt;. A typical set of status codes (200, 404, 500)  and actions (GET, POST, PUT, PATCH, DELETE) would create 15 unique streams. But, adding just one more label like &lt;code&gt;endpoint&lt;/code&gt; (/cart, /products, /customers) would triple this to 45 unique streams.&lt;/p&gt;
&lt;p&gt;To see an example of series labels and cardinality, refer to the 
    &lt;a href=&#34;/docs/loki/v3.7.x/query/logcli/logcli-tutorial/#checking-series-cardinality&#34;&gt;LogCLI tutorial&lt;/a&gt;.  As you can see, the cardinality for individual labels can be quite high, even before you begin combining labels for a particular log stream, which increases the cardinality even further.&lt;/p&gt;
&lt;p&gt;To view the cardinality of your current labels, you can use 
    &lt;a href=&#34;/docs/loki/v3.7.x/query/logcli/getting-started/&#34;&gt;logcli&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;logcli series &#39;{}&#39; --since=1h --analyze-labels&lt;/code&gt;&lt;/p&gt;
&lt;h2 id=&#34;impact-of-high-cardinality-in-loki&#34;&gt;Impact of high cardinality in Loki&lt;/h2&gt;
&lt;p&gt;High cardinality causes Loki to create many streams, especially when labels have many unique values, and when those values are short-lived (for example, active for seconds or minutes). This causes Loki to build a huge index, and to flush thousands of tiny chunks to the object store.&lt;/p&gt;
&lt;p&gt;Loki was not designed or built to support high cardinality label values. In fact, it was built for exactly the opposite. It was built for very long-lived streams and very low cardinality in the labels. In Loki, the fewer labels you use, the better.&lt;/p&gt;
&lt;p&gt;High cardinality can lead to significant performance degradation.&lt;/p&gt;
&lt;h2 id=&#34;avoiding-high-cardinality&#34;&gt;Avoiding high cardinality&lt;/h2&gt;
&lt;p&gt;To avoid high cardinality in Loki, you should:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Avoid assigning labels with unbounded values, for example timestamp, trace ID, order ID.&lt;/li&gt;
&lt;li&gt;Prefer static labels that describe the origin or context of the log message, for example, application, namespace, environment.&lt;/li&gt;
&lt;li&gt;Don&amp;rsquo;t assign &amp;ldquo;dynamic&amp;rdquo; labels, which are values from the log message itself, unless it is low-cardinality, or a long-lived value.&lt;/li&gt;
&lt;li&gt;Use structured metadata to store frequently-searched, high-cardinality metadata fields, such as customer IDs or transaction IDs, without impacting Loki&amp;rsquo;s index.&lt;/li&gt;
&lt;/ul&gt;


&lt;div class=&#34;admonition admonition-note&#34;&gt;&lt;blockquote&gt;&lt;p class=&#34;title text-uppercase&#34;&gt;Note&lt;/p&gt;&lt;p&gt;
    &lt;a href=&#34;/docs/loki/v3.7.x/get-started/labels/structured-metadata/&#34;&gt;Structured metadata&lt;/a&gt; is a feature in Loki and Cloud Logs that allows customers to store metadata that is too high cardinality for log lines, without needing to embed that information in log lines themselves.&lt;br /&gt;
It is a great home for metadata which is not easily embeddable in a log line, but is too high cardinality to be used effectively as a label. 
    &lt;a href=&#34;/docs/loki/v3.7.x/operations/bloom-filters/&#34;&gt;Query acceleration with Blooms&lt;/a&gt; also utilizes structured metadata.&lt;/p&gt;&lt;/blockquote&gt;&lt;/div&gt;

]]></content><description>&lt;h1 id="cardinality">Cardinality&lt;/h1>
&lt;p>The cardinality of a data attribute is the number of distinct values that the attribute can have. For example, a boolean column in a database, which can only have a value of either &lt;code>true&lt;/code> or &lt;code>false&lt;/code> has a cardinality of 2.&lt;/p></description></item><item><title>What is structured metadata</title><link>https://grafana.com/docs/loki/v3.7.x/get-started/labels/structured-metadata/</link><pubDate>Thu, 09 Apr 2026 02:28:18 +0000</pubDate><guid>https://grafana.com/docs/loki/v3.7.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.7.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;li&gt;If you are using &lt;a href=&#34;/docs/grafana-cloud/visualizations/simplified-exploration/logs/&#34;&gt;Logs Drilldown&lt;/a&gt; to visualize and explore your Loki logs.  You must set &lt;code&gt;discover_log_levels&lt;/code&gt; and &lt;code&gt;allow_structured_metadata&lt;/code&gt; to &lt;code&gt;true&lt;/code&gt; in your Loki configuration.&lt;/li&gt;
&lt;li&gt;If you are a large-scale customer, who is ingesting more than 75TB of logs a month and are using 
    &lt;a href=&#34;/docs/loki/v3.7.x/operations/bloom-filters/&#34;&gt;Bloom filters&lt;/a&gt; (Experimental), starting in 
    &lt;a href=&#34;/docs/loki/v3.7.x/release-notes/v3-3/&#34;&gt;Loki 3.3&lt;/a&gt; Bloom filters now utilize structured metadata.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;enable-or-disable-structured-metadata&#34;&gt;Enable or disable structured metadata&lt;/h2&gt;
&lt;p&gt;You enable structured metadata in the Loki config.yaml file.&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;YAML&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-yaml&#34;&gt;limits_config:
    allow_structured_metadata: true
    volume_enabled: true
    retention_period: 672h # 28 days retention&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;You can disable Structured Metadata by setting &lt;code&gt;allow_structured_metadata: false&lt;/code&gt; in the &lt;code&gt;limits_config&lt;/code&gt; section or set the command line argument &lt;code&gt;-validation.allow-structured-metadata=false&lt;/code&gt;. Note structured metadata is required to support ingesting OTLP data.&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.7.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 to extract and attach structured metadata to your log lines.
See the &lt;a href=&#34;/docs/alloy/latest/reference/components/loki/loki.process/#stagestructured_metadata&#34;&gt;Alloy &lt;code&gt;stage.structured_metadata&lt;/code&gt; block&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.7.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 &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;YAML&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-yaml&#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.7.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.7.x/query/log_queries/#keep-labels-expression&#34;&gt;Keep&lt;/a&gt; and 
    &lt;a href=&#34;/docs/loki/v3.7.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.7.x/configure/storage/#schema-config">Schema Config&lt;/a> for more details about schema versions.&lt;/p></description></item><item><title>Modify default OpenTelemetry labels</title><link>https://grafana.com/docs/loki/v3.7.x/get-started/labels/modify-default-labels/</link><pubDate>Thu, 09 Apr 2026 02:28:18 +0000</pubDate><guid>https://grafana.com/docs/loki/v3.7.x/get-started/labels/modify-default-labels/</guid><content><![CDATA[&lt;h1 id=&#34;modify-default-opentelemetry-labels&#34;&gt;Modify default OpenTelemetry labels&lt;/h1&gt;
&lt;p&gt;When Grafana Loki first started supporting OpenTelemetry, we selected a set of 
    &lt;a href=&#34;/docs/loki/v3.7.x/get-started/labels/#default-labels-for-opentelemetry&#34;&gt;default resource attributes to promote to labels&lt;/a&gt;. We included some labels such as k8s.pod.name to be consistent with the scrape configs we have been suggesting for many years for Grafana Alloy. However, Loki has evolved a lot over the years and with the introduction of Structured Metadata we no longer recommend indexing a few of the labels we included in the defaults as they often have very high 
    &lt;a href=&#34;/docs/loki/v3.7.x/get-started/labels/cardinality/&#34;&gt;cardinality&lt;/a&gt; and Structured Metadata is a much better place for them. We no longer recommend the following as default labels:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;k8s.pod.name&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;service.instance.id&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Because removing these resource attributes from labels would be a breaking change for existing users, they have not yet been deprecated. If you are a new user of Grafana Loki, we recommend that you modify your Grafana Alloy or OpenTelemetry Collector configuration to convert these resource attributes from index labels to structured metadata.&lt;/p&gt;
&lt;h2 id=&#34;alloy-configuration-file-example&#34;&gt;Alloy configuration file example&lt;/h2&gt;
&lt;p&gt;If you are using &lt;a href=&#34;/docs/alloy/latest/&#34;&gt;Grafana Alloy&lt;/a&gt; to collect logs, the following example shows how to update your &lt;code&gt;alloy.config&lt;/code&gt; file to demote &lt;code&gt;k8s.pod.name&lt;/code&gt; from an index label to structured metadata.&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;Alloy&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-alloy&#34;&gt;// discovery.kubernetes allows you to find scrape targets from Kubernetes resources.
// It watches cluster state and ensures targets are continually synced with what is currently running in your cluster.
discovery.kubernetes &amp;#34;pod&amp;#34; {
  role = &amp;#34;pod&amp;#34;
}

// discovery.relabel rewrites the label set of the input targets by applying one or more relabeling rules.
// If no rules are defined, then the input targets are exported as-is.
discovery.relabel &amp;#34;pod_logs&amp;#34; {
  targets = discovery.kubernetes.pod.targets

  // Label creation - &amp;#34;namespace&amp;#34; field from &amp;#34;__meta_kubernetes_namespace&amp;#34;
  rule {
    source_labels = [&amp;#34;__meta_kubernetes_namespace&amp;#34;]
    action = &amp;#34;replace&amp;#34;
    target_label = &amp;#34;namespace&amp;#34;
  }

  // Label creation - &amp;#34;pod&amp;#34; field from &amp;#34;__meta_kubernetes_pod_name&amp;#34;
  //rule {
  //  source_labels = [&amp;#34;__meta_kubernetes_pod_name&amp;#34;]
  //  action = &amp;#34;replace&amp;#34;
  //  target_label = &amp;#34;pod&amp;#34;
  //}


  // Label creation - &amp;#34;container&amp;#34; field from &amp;#34;__meta_kubernetes_pod_container_name&amp;#34;
  rule {
    source_labels = [&amp;#34;__meta_kubernetes_pod_container_name&amp;#34;]
    action = &amp;#34;replace&amp;#34;
    target_label = &amp;#34;container&amp;#34;
  }

  // Label creation -  &amp;#34;app&amp;#34; field from &amp;#34;__meta_kubernetes_pod_label_app_kubernetes_io_name&amp;#34;
  rule {
    source_labels = [&amp;#34;__meta_kubernetes_pod_label_app_kubernetes_io_name&amp;#34;]
    action = &amp;#34;replace&amp;#34;
    target_label = &amp;#34;app&amp;#34;
  }

  // Label creation -  &amp;#34;job&amp;#34; field from &amp;#34;__meta_kubernetes_namespace&amp;#34; and &amp;#34;__meta_kubernetes_pod_container_name&amp;#34;
  // Concatenate values __meta_kubernetes_namespace/__meta_kubernetes_pod_container_name
  rule {
    source_labels = [&amp;#34;__meta_kubernetes_namespace&amp;#34;, &amp;#34;__meta_kubernetes_pod_container_name&amp;#34;]
    action = &amp;#34;replace&amp;#34;
    target_label = &amp;#34;job&amp;#34;
    separator = &amp;#34;/&amp;#34;
    replacement = &amp;#34;$1&amp;#34;
  }

  // Label creation - &amp;#34;container&amp;#34; field from &amp;#34;__meta_kubernetes_pod_uid&amp;#34; and &amp;#34;__meta_kubernetes_pod_container_name&amp;#34;
  // Concatenate values __meta_kubernetes_pod_uid/__meta_kubernetes_pod_container_name.log
  rule {
    source_labels = [&amp;#34;__meta_kubernetes_pod_uid&amp;#34;, &amp;#34;__meta_kubernetes_pod_container_name&amp;#34;]
    action = &amp;#34;replace&amp;#34;
    target_label = &amp;#34;__path__&amp;#34;
    separator = &amp;#34;/&amp;#34;
    replacement = &amp;#34;/var/log/pods/*$1/*.log&amp;#34;
  }

  // Label creation -  &amp;#34;container_runtime&amp;#34; field from &amp;#34;__meta_kubernetes_pod_container_id&amp;#34;
  rule {
    source_labels = [&amp;#34;__meta_kubernetes_pod_container_id&amp;#34;]
    action = &amp;#34;replace&amp;#34;
    target_label = &amp;#34;container_runtime&amp;#34;
    regex = &amp;#34;^(\\S&amp;#43;):\\/\\/.&amp;#43;$&amp;#34;
    replacement = &amp;#34;$1&amp;#34;
  }
}

// loki.source.kubernetes tails logs from Kubernetes containers using the Kubernetes API.
loki.source.kubernetes &amp;#34;pod_logs&amp;#34; {
  targets    = discovery.relabel.pod_logs.output
  forward_to = [loki.process.pod_logs.receiver]
}

// loki.process receives log entries from other Loki components, applies one or more processing stages,
// and forwards the results to the list of receivers in the component&amp;#39;s arguments.
loki.process &amp;#34;pod_logs&amp;#34; {
  stage.static_labels {
      values = {
        cluster = &amp;#34;&amp;lt;CLUSTER_NAME&amp;gt;&amp;#34;,
      }
  }

  forward_to = [loki.write.&amp;lt;WRITE_COMPONENT_NAME&amp;gt;.receiver]
}&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;h2 id=&#34;kubernetes-monitoring-helm-chart-configuration-example&#34;&gt;Kubernetes Monitoring Helm chart configuration example&lt;/h2&gt;
&lt;p&gt;If you are using the &lt;a href=&#34;/docs/grafana-cloud/monitor-infrastructure/kubernetes-monitoring/&#34;&gt;Kubernetes Monitoring Helm chart&lt;/a&gt; to collect Kubernetes logs to send to Loki, the following example shows how to update the &lt;code&gt;values.yaml&lt;/code&gt; file for your Helm chart to demote &lt;code&gt;k8s.pod.name&lt;/code&gt; and &lt;code&gt;service.instance.id&lt;/code&gt; from index labels to structured metadata.&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;YAML&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-yaml&#34;&gt;# Enable pod log collection for the cluster. Will collect logs from all pods in both the meta and loki namespace. 

podLogs:
  enabled: true
  collector: alloy-singleton
  #List of attributes to use as index labels in loki
  labelsToKeep:
    - app
    - app_kubernetes_io_name
    - component
    - container
    - job
    - level
    - namespace
    - service_name
    - cluster
  gatherMethod: kubernetesApi
  namespaces:
    - meta
    - loki
  #This is the section that specifies to send k8s.pod.name and service.instance.id to structured metadata
  structuredMetadata:
    instance_id:
    pod:&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;h2 id=&#34;loki-configuration-example&#34;&gt;Loki configuration example&lt;/h2&gt;
&lt;p&gt;If you are running Loki in a Docker container or on-premises, here is an example of how to modify your Loki &lt;code&gt;values.yaml&lt;/code&gt; file to demote &lt;code&gt;k8s.pod.name&lt;/code&gt; and &lt;code&gt;service.instance.id&lt;/code&gt; from index labels to structured metadata.&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;YAML&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-yaml&#34;&gt;
distributor:
  otlp_config:
    # List of default otlp resource attributes to be picked as index labels - EDIT TO REMOVE k8s.pod.name AND service.instance.id FROM THE LIST
    # CLI flag: -distributor.otlp.default_resource_attributes_as_index_labels
    default_resource_attributes_as_index_labels: [service.name service.namespace deployment.environment deployment.environment.name cloud.region cloud.availability_zone k8s.cluster.name k8s.namespace.name k8s.container.name container.name k8s.replicaset.name k8s.deployment.name k8s.statefulset.name k8s.daemonset.name k8s.cronjob.name k8s.job.name]&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Kubernetes example &lt;code&gt;values.yaml&lt;/code&gt;:&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;YAML&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-yaml&#34;&gt;loki:
  distributor:
    otlp_config:
    # List of default otlp resource attributes to be picked as index labels - EDIT TO REMOVE k8s.pod.name AND service.instance.id FROM THE LIST
    # CLI flag: -distributor.otlp.default_resource_attributes_as_index_labels
      default_resource_attributes_as_index_labels: [service.name service.namespace deployment.environment deployment.environment.name cloud.region cloud.availability_zone k8s.cluster.name k8s.namespace.name k8s.container.name container.name k8s.replicaset.name k8s.deployment.name k8s.statefulset.name k8s.daemonset.name k8s.cronjob.name k8s.job.name]&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
]]></content><description>&lt;h1 id="modify-default-opentelemetry-labels">Modify default OpenTelemetry labels&lt;/h1>
&lt;p>When Grafana Loki first started supporting OpenTelemetry, we selected a set of
&lt;a href="/docs/loki/v3.7.x/get-started/labels/#default-labels-for-opentelemetry">default resource attributes to promote to labels&lt;/a>. We included some labels such as k8s.pod.name to be consistent with the scrape configs we have been suggesting for many years for Grafana Alloy. However, Loki has evolved a lot over the years and with the introduction of Structured Metadata we no longer recommend indexing a few of the labels we included in the defaults as they often have very high
&lt;a href="/docs/loki/v3.7.x/get-started/labels/cardinality/">cardinality&lt;/a> and Structured Metadata is a much better place for them. We no longer recommend the following as default labels:&lt;/p></description></item></channel></rss>