<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Manage a tenant on Grafana Labs</title><link>https://grafana.com/docs/enterprise-metrics/v2.1.x/tenant-management/</link><description>Recent content in Manage a tenant on Grafana Labs</description><generator>Hugo -- gohugo.io</generator><language>en</language><atom:link href="/docs/enterprise-metrics/v2.1.x/tenant-management/index.xml" rel="self" type="application/rss+xml"/><item><title>Setting per-tenant resource usage limits</title><link>https://grafana.com/docs/enterprise-metrics/v2.1.x/tenant-management/limits/</link><pubDate>Fri, 03 Apr 2026 19:43:06 +0000</pubDate><guid>https://grafana.com/docs/enterprise-metrics/v2.1.x/tenant-management/limits/</guid><content><![CDATA[&lt;h2 id=&#34;overview&#34;&gt;Overview&lt;/h2&gt;
&lt;p&gt;Per-tenant resource limits can be used to ensure a single tenant cannot monopolize the
resources of or threaten the stability of a Grafana Enterprise Metrics cluster. There are
limits available to tune usage of all parts of the metric read and write paths. For a complete
list of all available limits, refer to the &lt;a href=&#34;../../config/reference/#limits&#34;&gt;Grafana Mimir limits configuration&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Using the &lt;a href=&#34;../../admin-api/&#34;&gt;admin API&lt;/a&gt; of Grafana Enterprise Metrics, you
can easily set a &lt;em&gt;subset&lt;/em&gt; of these per-tenant limits.&lt;/p&gt;
&lt;p&gt;The following limits are supported via the admin API:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;ingestion_rate&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ingestion_burst_size&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;max_series_per_query&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;max_global_series_per_user&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;max_global_series_per_metric&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;max_global_exemplars_per_user&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ruler_max_rules_per_rule_group&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ruler_max_rule_groups_per_tenant&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;max_fetched_chunks_per_query&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;max_fetched_series_per_query&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;max_fetched_chunk_bytes_per_query&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;compactor_blocks_retention_period&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;setting-limits-via-the-admin-api&#34;&gt;Setting limits via the admin API&lt;/h2&gt;
&lt;p&gt;Limits can be set using the admin API when creating a new tenant or when modifying an existing
one.&lt;/p&gt;
&lt;p&gt;Create a JSON payload, &lt;code&gt;test1.json&lt;/code&gt;, for creating a new tenant that includes a subset of per-tenant limits.&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;JSON&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-json&#34;&gt;{
  &amp;#34;name&amp;#34;: &amp;#34;test1&amp;#34;,
  &amp;#34;display_name&amp;#34;: &amp;#34;Test Instance 1&amp;#34;,
  &amp;#34;status&amp;#34;: &amp;#34;active&amp;#34;,
  &amp;#34;cluster&amp;#34;: &amp;#34;enterprise-metrics-dev&amp;#34;,
  &amp;#34;limits&amp;#34;: {
    &amp;#34;max_series_per_query&amp;#34;: 42000,
    &amp;#34;max_global_series_per_user&amp;#34;: 42000,
    &amp;#34;compactor_blocks_retention_period&amp;#34;: &amp;#34;24h&amp;#34;
  }
}&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Use &lt;code&gt;curl&lt;/code&gt; to POST the data to the admin API.&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;console&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-console&#34;&gt;$ curl -u :$API_TOKEN localhost:8080/admin/api/v3/tenants \
    -X POST --data @test1.json&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Read the newly created tenant.&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;console&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-console&#34;&gt;curl -u :$API_TOKEN localhost:8080/admin/api/v3/tenants/test1 | jq
{
  &amp;#34;name&amp;#34;: &amp;#34;test1&amp;#34;,
  &amp;#34;display_name&amp;#34;: &amp;#34;Test Instance 1&amp;#34;,
  &amp;#34;created_at&amp;#34;: &amp;#34;2020-07-13T17:37:59.341728283Z&amp;#34;,
  &amp;#34;status&amp;#34;: &amp;#34;active&amp;#34;,
  &amp;#34;cluster&amp;#34;: &amp;#34;enterprise-metrics-dev&amp;#34;,
  &amp;#34;limits&amp;#34;: {
    &amp;#34;ingestion_rate&amp;#34;: 350000,
    &amp;#34;ingestion_burst_size&amp;#34;: 350000,
    &amp;#34;max_series_per_query&amp;#34;: 42000,
    &amp;#34;max_global_series_per_user&amp;#34;: 42000,
    &amp;#34;max_global_series_per_metric&amp;#34;: 300000,
    &amp;#34;max_global_exemplars_per_user&amp;#34;: 0,
    &amp;#34;ruler_max_rules_per_rule_group&amp;#34;: 0,
    &amp;#34;ruler_max_rule_groups_per_tenant&amp;#34;: 0,
    &amp;#34;max_fetched_chunks_per_query&amp;#34;: 0,
    &amp;#34;max_fetched_series_per_query&amp;#34;: 0,
    &amp;#34;max_fetched_chunk_bytes_per_query&amp;#34;: 0,
    &amp;#34;compactor_blocks_retention_period&amp;#34;: &amp;#34;24h&amp;#34;
  }
}&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Note that all available limit settings are populated, even ones that we did not include in our POST
request. Any limit settings not included when a new tenant is created with &lt;em&gt;some&lt;/em&gt; limit settings
are populated from the global default limits. This also applies when limits are added to a tenant
that previously did not have them: any limit settings that are not included will be populated from
the global default limits.&lt;/p&gt;
&lt;h2 id=&#34;removing-limits-via-the-admin-api&#34;&gt;Removing limits via the admin API&lt;/h2&gt;
&lt;p&gt;Limits can be removed from a tenant using the admin API by modifying the tenant.&lt;/p&gt;
&lt;p&gt;Create a JSON payload, &lt;code&gt;test1-update.json&lt;/code&gt;, that doesn&amp;rsquo;t include the &lt;code&gt;limits&lt;/code&gt; field.&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;JSON&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-json&#34;&gt;{
  &amp;#34;display_name&amp;#34;: &amp;#34;Test Instance 1&amp;#34;,
  &amp;#34;status&amp;#34;: &amp;#34;active&amp;#34;,
  &amp;#34;cluster&amp;#34;: &amp;#34;enterprise-metrics-dev&amp;#34;
}&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Use &lt;code&gt;curl&lt;/code&gt; to PUT the data to the admin API.&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;console&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-console&#34;&gt;$ curl -u :$API_TOKEN localhost:8080/admin/api/v3/tenants/test1 \
    -X PUT --data @test1-update.json | jq
{
  &amp;#34;name&amp;#34;: &amp;#34;test1&amp;#34;,
  &amp;#34;display_name&amp;#34;: &amp;#34;Test Instance 1&amp;#34;,
  &amp;#34;created_at&amp;#34;: &amp;#34;2020-07-13T17:37:59.341728283Z&amp;#34;,
  &amp;#34;status&amp;#34;: &amp;#34;active&amp;#34;,
  &amp;#34;cluster&amp;#34;: &amp;#34;enterprise-metrics-dev&amp;#34;
}&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;The modified tenant object is included in the update response.&lt;/p&gt;
&lt;h2 id=&#34;limit-sources&#34;&gt;Limit sources&lt;/h2&gt;
&lt;p&gt;Limits applied to a tenant are only taken from a single location at a time:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Per-tenant limits set by the &lt;a href=&#34;../../admin-api/&#34;&gt;admin API&lt;/a&gt;, backfilled with global defaults.&lt;/li&gt;
&lt;li&gt;Per-tenant limits set by a &lt;a href=&#34;/docs/mimir/latest/operators-guide/configuring/about-runtime-configuration/&#34;&gt;runtime configuration file&lt;/a&gt;, backfilled with global defaults.&lt;/li&gt;
&lt;li&gt;Global default limits set by a &lt;a href=&#34;../../config/reference/#limits&#34;&gt;configuration file&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;These locations are checked for limits to apply to operations, in that order. Once a location for
limits to apply to an operation is found, &lt;strong&gt;no other locations are checked&lt;/strong&gt;. The effect of this is
that if you set limits for a tenant using the admin API, any limit settings for &lt;em&gt;that&lt;/em&gt; tenant
in a runtime configuration file will be ignored.&lt;/p&gt;
&lt;h2 id=&#34;implementation&#34;&gt;Implementation&lt;/h2&gt;
&lt;p&gt;Enforcing limits based on values set with the admin API requires periodically making requests
to object storage (S3, GCS, etc.) to get the most up to date limits for each tenant. This means
that based on the period you have configured to refresh tenant-based limits (1 minute by default),
N GET requests and 1 LIST request will be made to object storage, where N is the number of
tenants in your Grafana Enterprise Metrics cluster.&lt;/p&gt;
]]></content><description>&lt;h2 id="overview">Overview&lt;/h2>
&lt;p>Per-tenant resource limits can be used to ensure a single tenant cannot monopolize the
resources of or threaten the stability of a Grafana Enterprise Metrics cluster. There are
limits available to tune usage of all parts of the metric read and write paths. For a complete
list of all available limits, refer to the &lt;a href="../../config/reference/#limits">Grafana Mimir limits configuration&lt;/a>.&lt;/p></description></item><item><title>Using label-based access control (LBAC)</title><link>https://grafana.com/docs/enterprise-metrics/v2.1.x/tenant-management/lbac/</link><pubDate>Fri, 03 Apr 2026 19:43:06 +0000</pubDate><guid>https://grafana.com/docs/enterprise-metrics/v2.1.x/tenant-management/lbac/</guid><content><![CDATA[&lt;h2 id=&#34;overview&#34;&gt;Overview&lt;/h2&gt;
&lt;p&gt;Label-based access control can be used to create access policies that will only allow for data to be queried that meets specific label requirements. The feature allows multiple sets of &lt;a href=&#34;https://prometheus.io/docs/prometheus/latest/querying/basics/#time-series-selectors&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;Prometheus label selectors&lt;/a&gt; to be associated with a policy and queries will only return data from series that match at least one of the provided selectors. This correlates to &lt;a href=&#34;https://en.wikipedia.org/wiki/Disjunctive_normal_form&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;disjunctive normal form&lt;/a&gt; which allows any required policy to be expressed.&lt;/p&gt;
&lt;h2 id=&#34;setting-up-a-label-policy&#34;&gt;Setting up a label policy&lt;/h2&gt;
&lt;p&gt;Label policies are set when creating an access policy on a per tenant basis. This means each tenant associated with an access policy can have a unique label policy.&lt;/p&gt;
&lt;figure
    class=&#34;figure-wrapper figure-wrapper__lightbox w-100p &#34;
    style=&#34;max-width: 900px;&#34;
    itemprop=&#34;associatedMedia&#34;
    itemscope=&#34;&#34;
    itemtype=&#34;http://schema.org/ImageObject&#34;
  &gt;&lt;a
        class=&#34;lightbox-link captioned&#34;
        href=&#34;../create-lbac-policy.png&#34;
        itemprop=&#34;contentUrl&#34;
      &gt;&lt;div class=&#34;img-wrapper w-100p h-auto&#34;&gt;&lt;img
          class=&#34;lazyload mb-0&#34;
          data-src=&#34;../create-lbac-policy.png&#34;alt=&#34;Create LBAC policy&#34;title=&#34;Create LBAC policy&#34;/&gt;
        &lt;noscript&gt;
          &lt;img
            src=&#34;../create-lbac-policy.png&#34;
            alt=&#34;Create LBAC policy&#34;title=&#34;Create LBAC policy&#34;/&gt;
        &lt;/noscript&gt;&lt;/div&gt;&lt;figcaption class=&#34;w-100p caption text-gray-13  &#34;&gt;Create LBAC policy&lt;/figcaption&gt;&lt;/a&gt;&lt;/figure&gt;
&lt;hr /&gt;
&lt;h2 id=&#34;examples&#34;&gt;Examples&lt;/h2&gt;
&lt;h3 id=&#34;exclude-a-label&#34;&gt;Exclude a label&lt;/h3&gt;
&lt;p&gt;One common use case for creating an LBAC policy is to exclude metrics with a specific label. For instance, a label policy that excludes all series with the label &lt;code&gt;secret=true&lt;/code&gt; would be created by just adding a select with &lt;code&gt;secret!=&amp;quot;true&amp;quot;&lt;/code&gt; when creating an access policy. This can be seen in the image below:&lt;/p&gt;
&lt;figure
    class=&#34;figure-wrapper figure-wrapper__lightbox w-100p &#34;
    style=&#34;max-width: 900px;&#34;
    itemprop=&#34;associatedMedia&#34;
    itemscope=&#34;&#34;
    itemtype=&#34;http://schema.org/ImageObject&#34;
  &gt;&lt;a
        class=&#34;lightbox-link captioned&#34;
        href=&#34;../label-exclude.png&#34;
        itemprop=&#34;contentUrl&#34;
      &gt;&lt;div class=&#34;img-wrapper w-100p h-auto&#34;&gt;&lt;img
          class=&#34;lazyload mb-0&#34;
          data-src=&#34;../label-exclude.png&#34;alt=&#34;Create exclude label&#34;title=&#34;Create exclude label&#34;/&gt;
        &lt;noscript&gt;
          &lt;img
            src=&#34;../label-exclude.png&#34;
            alt=&#34;Create exclude label&#34;title=&#34;Create exclude label&#34;/&gt;
        &lt;/noscript&gt;&lt;/div&gt;&lt;figcaption class=&#34;w-100p caption text-gray-13  &#34;&gt;Create exclude label&lt;/figcaption&gt;&lt;/a&gt;&lt;/figure&gt;
&lt;h3 id=&#34;exclude-a-metric&#34;&gt;Exclude a metric&lt;/h3&gt;
&lt;p&gt;Expanding upon the previous example, lets say we wanted to create an access policy that only excludes metrics with the label &lt;code&gt;secret=true&lt;/code&gt; on the metric named &lt;code&gt;sensitive_requests_total&lt;/code&gt;. Since the name of a metric is actually just a label with the key &lt;code&gt;__name__&lt;/code&gt;, we can leverage the existing LBAC label selector syntax to enforce this:&lt;/p&gt;
&lt;figure
    class=&#34;figure-wrapper figure-wrapper__lightbox w-100p &#34;
    style=&#34;max-width: 900px;&#34;
    itemprop=&#34;associatedMedia&#34;
    itemscope=&#34;&#34;
    itemtype=&#34;http://schema.org/ImageObject&#34;
  &gt;&lt;a
        class=&#34;lightbox-link captioned&#34;
        href=&#34;../metric-exclude.png&#34;
        itemprop=&#34;contentUrl&#34;
      &gt;&lt;div class=&#34;img-wrapper w-100p h-auto&#34;&gt;&lt;img
          class=&#34;lazyload mb-0&#34;
          data-src=&#34;../metric-exclude.png&#34;alt=&#34;Create exclude metric&#34;title=&#34;Create exclude metric&#34;/&gt;
        &lt;noscript&gt;
          &lt;img
            src=&#34;../metric-exclude.png&#34;
            alt=&#34;Create exclude metric&#34;title=&#34;Create exclude metric&#34;/&gt;
        &lt;/noscript&gt;&lt;/div&gt;&lt;figcaption class=&#34;w-100p caption text-gray-13  &#34;&gt;Create exclude metric&lt;/figcaption&gt;&lt;/a&gt;&lt;/figure&gt;
&lt;p&gt;You may notice above that two different selectors where added to enforce the policy. Specifically:&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;{secret!=&amp;#34;true&amp;#34;, __name__=&amp;#34;sensitive_requests_total&amp;#34;}&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;and&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;{__name__!=&amp;#34;sensitive_requests_total&amp;#34;}&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;The first selector will match when returning a series from the metrics &lt;code&gt;sensitive_requests_total&lt;/code&gt; and will ensure all of the returned series do not have the &lt;code&gt;secret: true&lt;/code&gt; label. However, when requesting a metric besides &lt;code&gt;sensitive_requests_total&lt;/code&gt;, the second label selector will match and return any data even if it has the &lt;code&gt;secret: true&lt;/code&gt; label.&lt;/p&gt;
]]></content><description>&lt;h2 id="overview">Overview&lt;/h2>
&lt;p>Label-based access control can be used to create access policies that will only allow for data to be queried that meets specific label requirements. The feature allows multiple sets of &lt;a href="https://prometheus.io/docs/prometheus/latest/querying/basics/#time-series-selectors" target="_blank" rel="noopener noreferrer">Prometheus label selectors&lt;/a> to be associated with a policy and queries will only return data from series that match at least one of the provided selectors. This correlates to &lt;a href="https://en.wikipedia.org/wiki/Disjunctive_normal_form" target="_blank" rel="noopener noreferrer">disjunctive normal form&lt;/a> which allows any required policy to be expressed.&lt;/p></description></item><item><title>Cardinality analysis</title><link>https://grafana.com/docs/enterprise-metrics/v2.1.x/tenant-management/cardinality-analysis/</link><pubDate>Fri, 03 Apr 2026 19:43:06 +0000</pubDate><guid>https://grafana.com/docs/enterprise-metrics/v2.1.x/tenant-management/cardinality-analysis/</guid><content><![CDATA[&lt;h2 id=&#34;overview&#34;&gt;Overview&lt;/h2&gt;
&lt;p&gt;Grafana Enterprise Metrics provides the ability to understand the cardinality of your metrics and labels using &lt;a href=&#34;#dashboards&#34;&gt;Cardinality analysis dashboards&lt;/a&gt;
that are shipped with the Grafana Enterprise Metrics plugin or via an &lt;a href=&#34;#http-api&#34;&gt;API&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The APIs and dashboards help you understand the active time series in GEM. An active time series is one that has not yet
been written to long-term storage.&lt;/p&gt;
&lt;h2 id=&#34;configuration&#34;&gt;Configuration&lt;/h2&gt;
&lt;p&gt;The API endpoints are disabled by default. Use one of the following approaches to enable or disable the endpoints for all tenants:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Add the CLI flag &lt;code&gt;-querier.cardinality-analysis-enabled=true&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Set &lt;code&gt;cardinality_analysis_enabled&lt;/code&gt; to &lt;code&gt;true&lt;/code&gt; in the &lt;code&gt;limits&lt;/code&gt; section of the &lt;a href=&#34;/docs/mimir/latest/operators-guide/configuring/reference-configuration-parameters/#limits&#34;&gt;global configuration file&lt;/a&gt; as shown below:&lt;/li&gt;
&lt;/ul&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:
  cardinality_analysis_enabled: true&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;To selectively disable the endpoints for some tenants (if it&amp;rsquo;s been enabled for all tenants), or enable the endpoints for some tenants (when it is globally disabled), use the &lt;a href=&#34;/docs/mimir/latest/operators-guide/configuring/about-runtime-configuration/&#34;&gt;Runtime Configuration file&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&#34;limitations&#34;&gt;Limitations&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;The cardinality analysis dashboards only work for single-tenant data sources. Similarly, the cardinality analysis APIs will only return cardinality information for a single tenant at a time. You cannot get a global view of the cardinality of multiple tenants simultaneously. This means that any call to the API where you provide multiple tenants in the &lt;code&gt;username&lt;/code&gt; field will fail. For example, &lt;code&gt;team-a|team-b&lt;/code&gt; will fail, but &lt;code&gt;team-a&lt;/code&gt; or &lt;code&gt;team-b&lt;/code&gt; will succeed.&lt;/li&gt;
&lt;li&gt;The cardinality analysis dashboards do not work for data sources that use label-based access controls. Similarly, calls to the cardinality analysis APIs that use a token for an access policy with label selectors also fail.&lt;/li&gt;
&lt;li&gt;The cardinality analysis APIs and dashboards will only work if you are running GEM using block storage. They are incompatible with chunks storage.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;operational-considerations&#34;&gt;Operational considerations&lt;/h2&gt;
&lt;p&gt;We do not expect this new and experimental API to negatively affect the performance of ingesters in a GEM cluster. To be sure, monitor the cluster after enabling this feature.&lt;/p&gt;
&lt;p&gt;To monitor the performance of the cardinality endpoints, use the exposed GEM API endpoints metrics.&lt;/p&gt;
&lt;p&gt;The following example query returns the queries-per-second to the cardinality analysis endpoints:&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;sum by (route) (
    rate(cortex_querier_request_duration_seconds_sum{
        route=~&amp;#34;prometheus_api_v1_cardinality_label_values|prometheus_api_v1_cardinality_label_names&amp;#34;
    }[1m])
)&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;To monitor the performance of the whole cluster after enabling cardinality analysis, use the self-monitoring dashboards that are included in the GEM plugin.&lt;/p&gt;
&lt;h2 id=&#34;dashboards&#34;&gt;Dashboards&lt;/h2&gt;
&lt;p&gt;The GEM plugin provides several useful dashboards that visualize and let you explore the data from this API.&lt;/p&gt;
&lt;h3 id=&#34;adding-the-cardinality-analysis-dashboards-to-grafana-enterprise&#34;&gt;Adding the cardinality analysis dashboards to Grafana Enterprise&lt;/h3&gt;
&lt;p&gt;The cardinality analysis dashboards are automatically installed if you install the Grafana Enterprise Metrics plugin. However, in the event that you do not see the dashboards or someone accidentally deletes them, add them back:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Go to &lt;code&gt;Configuration &amp;gt; Plugins &amp;gt; Grafana Enterprise Metrics &amp;gt; Dashboards&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Install the dashboards : &lt;code&gt;Cardinality management - overview&lt;/code&gt;, &lt;code&gt;Cardinality management - metrics&lt;/code&gt; and &lt;code&gt;Cardinality management - labels&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;img
  class=&#34;lazyload d-inline-block&#34;
  data-src=&#34;../cardinality-analysis-dashboards-install.png&#34;
  alt=&#34;install-dashboards&#34;/&gt;&lt;/p&gt;
&lt;h3 id=&#34;cardinality-management---overview-dashboard&#34;&gt;Cardinality management - overview dashboard&lt;/h3&gt;
&lt;p&gt;This dashboard shows the cardinality for the selected data source.&lt;/p&gt;
&lt;p&gt;&lt;img
  class=&#34;lazyload d-inline-block&#34;
  data-src=&#34;../cardinality-analysis-dashboard.png&#34;
  alt=&#34;cardinality-analysis-dashboard-example&#34;/&gt;&lt;/p&gt;
&lt;h3 id=&#34;cardinality-management---metrics-dashboard&#34;&gt;Cardinality management - metrics dashboard&lt;/h3&gt;
&lt;p&gt;This dashboard helps you understand the cardinality of an individual metric. At the top of the dashboard, you can select which metric you want to explore.&lt;/p&gt;
&lt;p&gt;&lt;img
  class=&#34;lazyload d-inline-block&#34;
  data-src=&#34;../cardinality-analysis-metrics-drill-down.png&#34;
  alt=&#34;cardinality-analysis-metrics-drill-down-dashboard-example&#34;/&gt;&lt;/p&gt;
&lt;h3 id=&#34;cardinality-management---labels-dashboard&#34;&gt;Cardinality management - labels dashboard&lt;/h3&gt;
&lt;p&gt;This dashboard shows a cardinality report for the selected label. For a given label name, it shows you which label values are attached to the most series. It also shows you the highest cardinality metrics for a given label&amp;lt;&amp;gt;value pair.&lt;/p&gt;
&lt;p&gt;&lt;img
  class=&#34;lazyload d-inline-block&#34;
  data-src=&#34;../cardinality-analysis-labels-drill-down.png&#34;
  alt=&#34;cardinality-analysis-labels-drill-down-dashboard-example&#34;/&gt;&lt;/p&gt;
&lt;h2 id=&#34;http-api&#34;&gt;HTTP API&lt;/h2&gt;
&lt;p&gt;You can use two API endpoints to understand a tenant&amp;rsquo;s metrics and label cardinality: &lt;code&gt;label_names&lt;/code&gt; (&lt;code&gt;/api/v1/cardinality/label_names&lt;/code&gt;) and &lt;code&gt;label_values&lt;/code&gt; (&lt;code&gt;/api/v1/cardinality/label_values&lt;/code&gt;). The cardinality analysis dashboards display information returned from these endpoints.&lt;/p&gt;
&lt;p&gt;Because these endpoints generate their cardinality report using only values from currently opened TSDBs (time series databases) in the ingesters, two subsequent calls can return completely different results if an ingester cut or truncated an old block and opened a new one between calls.&lt;/p&gt;
&lt;p&gt;Both API endpoints require authentication. Specifically, the user must provide a token which gives them &lt;code&gt;metrics: read&lt;/code&gt; access for that tenant.&lt;/p&gt;
&lt;h3 id=&#34;label-names-cardinality-endpoint&#34;&gt;Label names cardinality endpoint&lt;/h3&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;GET,POST &amp;lt;prometheus-http-prefix&amp;gt;/api/v1/cardinality/label_names

# Legacy
GET,POST &amp;lt;legacy-http-prefix&amp;gt;/api/v1/cardinality/label_names&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Returns realtime label names cardinality across all ingesters, for the authenticated tenant, in &lt;code&gt;JSON&lt;/code&gt; format.
It counts distinct label values per label name.&lt;/p&gt;
&lt;p&gt;The items in the field &lt;code&gt;cardinality&lt;/code&gt; are sorted by &lt;code&gt;label_values_count&lt;/code&gt; in descending order and by &lt;code&gt;label_name&lt;/code&gt; in ascending order.&lt;/p&gt;
&lt;p&gt;The count of items returned is limited by &lt;code&gt;limit&lt;/code&gt; request parameter.&lt;/p&gt;
&lt;h4 id=&#34;request-parameters&#34;&gt;Request parameters&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;selector&lt;/strong&gt; - &lt;em&gt;optional&lt;/em&gt; - specifies PromQL selector that will be used to filter series that must be analyzed.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;limit&lt;/strong&gt; - &lt;em&gt;optional&lt;/em&gt; - specifies max count of items in field &lt;code&gt;cardinality&lt;/code&gt; in response (default=20, min=0, max=500)&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&#34;example&#34;&gt;Example:&lt;/h4&gt;
&lt;p&gt;To understand which labels attached to the metric &lt;code&gt;flower_events_created&lt;/code&gt; have the most values, use the following command:&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;console&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-console&#34;&gt;$ curl -u &amp;#34;&amp;lt;tenant-id&amp;gt;:$API_TOKEN&amp;#34; &amp;#34;&amp;lt;host and port&amp;gt;/prometheus/api/v1/cardinality/label_names?limit=2&amp;amp;selector=\{__name__=&amp;#39;flower_events_created&amp;#39;\}&amp;#34; | jq&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&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;JSON&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-json&#34;&gt;{
  &amp;#34;label_values_count_total&amp;#34;: 206,
  &amp;#34;label_names_count&amp;#34;: 12,
  &amp;#34;cardinality&amp;#34;: [
    {
      &amp;#34;label_name&amp;#34;: &amp;#34;worker&amp;#34;,
      &amp;#34;label_values_count&amp;#34;: 162
    },
    {
      &amp;#34;label_name&amp;#34;: &amp;#34;task&amp;#34;,
      &amp;#34;label_values_count&amp;#34;: 29
    }
  ]
}&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;From this we see that the metric &lt;code&gt;flower_events_created&lt;/code&gt; has 12 different label names attached to it. Across those 12 label names, there are 206 total values. The label &amp;ldquo;worker&amp;rdquo; has 162 values, and the label &amp;ldquo;task&amp;rdquo; has 29 values. Not shown are the other label names, since the sample command set &lt;code&gt;limit=2&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;If the &lt;code&gt;flower_events_created&lt;/code&gt; selector were omitted, the API call&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;console&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-console&#34;&gt;$ curl -u &amp;#34;&amp;lt;tenant-id&amp;gt;:$API_TOKEN&amp;#34; &amp;#34;&amp;lt;host and port&amp;gt;/prometheus/api/v1/cardinality/label_names?limit=2&amp;#34; | jq&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;would return the label names with the highest count of values across the entire tenant.&lt;/p&gt;
&lt;h4 id=&#34;response-schema&#34;&gt;Response schema&lt;/h4&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;JSON&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-json&#34;&gt;{
  &amp;#34;label_values_count_total&amp;#34;: &amp;lt;number&amp;gt;,
  &amp;#34;label_names_count&amp;#34;: &amp;lt;number&amp;gt;,
  &amp;#34;cardinality&amp;#34;: [
    {
      &amp;#34;label_name&amp;#34;: &amp;lt;string&amp;gt;,
      &amp;#34;label_values_count&amp;#34;: &amp;lt;number&amp;gt;
    }
  ]
}&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;h3 id=&#34;label-values-cardinality-endpoint&#34;&gt;Label values cardinality endpoint&lt;/h3&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;GET,POST &amp;lt;prometheus-http-prefix&amp;gt;/api/v1/cardinality/label_values

# Legacy
GET,POST &amp;lt;legacy-http-prefix&amp;gt;/api/v1/cardinality/label_values&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Returns realtime label values cardinality associated with request parameter &lt;code&gt;label_names[]&lt;/code&gt; across all ingesters, for the authenticated tenant, in &lt;code&gt;JSON&lt;/code&gt; format.
It returns the series count per label value for each label in the request parameter &lt;code&gt;label_names[]&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;The items in the field &lt;code&gt;labels&lt;/code&gt; are sorted by &lt;code&gt;series_count&lt;/code&gt; in descending order and by &lt;code&gt;label_name&lt;/code&gt; in ascending order.
The items in the field &lt;code&gt;cardinality&lt;/code&gt; are sorted by &lt;code&gt;series_count&lt;/code&gt; in descending order and by &lt;code&gt;label_value&lt;/code&gt; in ascending order.&lt;/p&gt;
&lt;p&gt;The count of &lt;code&gt;cardinality&lt;/code&gt; items is limited by request parameter &lt;code&gt;limit&lt;/code&gt;.&lt;/p&gt;
&lt;h4 id=&#34;request-parameters-1&#34;&gt;Request parameters&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;label_names[]&lt;/strong&gt; - &lt;em&gt;required&lt;/em&gt; - specifies labels for which cardinality must be provided.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;selector&lt;/strong&gt; - &lt;em&gt;optional&lt;/em&gt; - specifies PromQL selector that will be used to filter series that must be analyzed.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;limit&lt;/strong&gt; - &lt;em&gt;optional&lt;/em&gt; - specifies max count of items in field &lt;code&gt;cardinality&lt;/code&gt; in response (default=20, min=0, max=500).&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&#34;example-1-label-values-cardinality&#34;&gt;Example 1 (label values cardinality):&lt;/h4&gt;
&lt;p&gt;In case we want to understand which label values have the highest number of &lt;code&gt;flower_events_created&lt;/code&gt; series associated with them, we can execute:&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;console&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-console&#34;&gt;$ curl -u &amp;#34;&amp;lt;tenant-id&amp;gt;:$API_TOKEN&amp;#34; &amp;#34;&amp;lt;host and port&amp;gt;/prometheus/api/v1/cardinality/label_values?label_names[]=worker&amp;amp;label_names[]=agent&amp;amp;limit=2&amp;amp;selector=\{__name__=&amp;#39;flower_events_created&amp;#39;\}&amp;#34; | jq&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&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;JSON&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-json&#34;&gt;{
  &amp;#34;series_count_total&amp;#34;: 5472781,
  &amp;#34;labels&amp;#34;: [
    {
      &amp;#34;label_name&amp;#34;: &amp;#34;worker&amp;#34;,
      &amp;#34;label_values_count&amp;#34;: 162,
      &amp;#34;series_count&amp;#34;: 1307,
      &amp;#34;cardinality&amp;#34;: [
        {
          &amp;#34;label_value&amp;#34;: &amp;#34;aws-worker&amp;#34;,
          &amp;#34;series_count&amp;#34;: 67
        },
        {
          &amp;#34;label_value&amp;#34;: &amp;#34;gcp-worker&amp;#34;,
          &amp;#34;series_count&amp;#34;: 66
        }
      ]
    },
    {
      &amp;#34;label_name&amp;#34;: &amp;#34;agent&amp;#34;,
      &amp;#34;label_values_count&amp;#34;: 2,
      &amp;#34;series_count&amp;#34;: 11,
      &amp;#34;cardinality&amp;#34;: [
        {
          &amp;#34;label_value&amp;#34;: &amp;#34;grafana-agent&amp;#34;,
          &amp;#34;series_count&amp;#34;: 10
        },
        {
          &amp;#34;label_value&amp;#34;: &amp;#34;jaeger-agent&amp;#34;,
          &amp;#34;series_count&amp;#34;: 1
        }
      ]
    }
  ]
}&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;From this, we see that there are 5,472,781 series with the metric name &lt;code&gt;flower_events_created.&lt;/code&gt; Of those 5,472,781 series, there are 67 series with &lt;code&gt;worker=aws-worker&lt;/code&gt; and 66 series with &lt;code&gt;worker=gcp-worker&lt;/code&gt;. From the &lt;code&gt;series_count&lt;/code&gt;, there are 1307 series with the label &lt;code&gt;worker&lt;/code&gt; (across all 162 values of &lt;code&gt;worker&lt;/code&gt;).&lt;/p&gt;
&lt;p&gt;Similarly, of the 5,472,781 total series, there are 10 series with &lt;code&gt;agent=grafana-agent&lt;/code&gt; and 1 series with &lt;code&gt;agent=jaeger-agent&lt;/code&gt;. From the &lt;code&gt;series_count&lt;/code&gt; there are 11 total series with the label &lt;code&gt;agent&lt;/code&gt; (across all 2 values of &lt;code&gt;agent&lt;/code&gt;).&lt;/p&gt;
&lt;h4 id=&#34;example-2-metric-names-cardinality&#34;&gt;Example 2 (metric names cardinality):&lt;/h4&gt;
&lt;p&gt;In case we want to understand which metrics have the highest cardinality (i.e. have the most time series) you can look at
the cardinality of the &lt;code&gt;__name__&lt;/code&gt; label.&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;console&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-console&#34;&gt;$ curl -u &amp;#34;&amp;lt;tenant-id&amp;gt;:$API_TOKEN&amp;#34; &amp;#34;&amp;lt;host and port&amp;gt;/prometheus/api/v1/cardinality/label_values?label_names[]=__name__&amp;amp;limit=2&amp;#34; | jq&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&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;JSON&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-json&#34;&gt;{
  &amp;#34;series_count_total&amp;#34;: 1307,
  &amp;#34;labels&amp;#34;: [
    {
      &amp;#34;label_name&amp;#34;: &amp;#34;__name__&amp;#34;,
      &amp;#34;label_values_count&amp;#34;: 162,
      &amp;#34;series_count&amp;#34;: 1307,
      &amp;#34;cardinality&amp;#34;: [
        {
          &amp;#34;label_value&amp;#34;: &amp;#34;flower_events_created&amp;#34;,
          &amp;#34;series_count&amp;#34;: 67
        },
        {
          &amp;#34;label_value&amp;#34;: &amp;#34;flower_events_consumed&amp;#34;,
          &amp;#34;series_count&amp;#34;: 66
        }
      ]
    }
  ]
}&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;In this example, there are 1307 total active time series for the tenant named &lt;code&gt;tenant-id&lt;/code&gt;. As there are 162 values for the label &lt;code&gt;__name__&lt;/code&gt;, we know this means there are 162 metrics for this tenant. The &lt;code&gt;label_value&lt;/code&gt; in the &lt;code&gt;cardinality&lt;/code&gt; part of the payload are the names of the highest cardinality metrics. In this example, we see that metric &lt;code&gt;flower_events_created&lt;/code&gt; has 67 series associated with it and metric &lt;code&gt;flower_events_consumed&lt;/code&gt; has 66 series associated with it.&lt;/p&gt;
&lt;h4 id=&#34;response-schema-1&#34;&gt;Response schema&lt;/h4&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;JSON&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-json&#34;&gt;{
  &amp;#34;series_count_total&amp;#34;: &amp;lt;number&amp;gt;,
  &amp;#34;labels&amp;#34;: [
    {
      &amp;#34;label_name&amp;#34;: &amp;lt;string&amp;gt;,
      &amp;#34;label_values_count&amp;#34;: &amp;lt;number&amp;gt;,
      &amp;#34;series_count&amp;#34;: &amp;lt;number&amp;gt;,
      &amp;#34;cardinality&amp;#34;: [
        {
          &amp;#34;label_value&amp;#34;: &amp;lt;string&amp;gt;,
          &amp;#34;series_count&amp;#34;: &amp;lt;number&amp;gt;
        }
      ]
    }
  ]
}&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;series_count_total&lt;/strong&gt; - total number of series across opened TSDBs in all ingesters&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;labels[].label_name&lt;/strong&gt; - label name requested via the request parameter &lt;code&gt;label_names[]&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;labels[].label_values_count&lt;/strong&gt; - total number of label values for the label name (note that dependent on the &lt;code&gt;limit&lt;/code&gt; request parameter it is possible that not all label values are present in &lt;code&gt;cardinality&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;labels[].series_count&lt;/strong&gt; - total number of series having &lt;code&gt;labels[].label_name&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;labels[].cardinality[].label_value&lt;/strong&gt; - label value associated with &lt;code&gt;labels[].label_name&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;labels[].cardinality[].series_count&lt;/strong&gt; - total number of series having &lt;code&gt;label_value&lt;/code&gt; for &lt;code&gt;label_name&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
]]></content><description>&lt;h2 id="overview">Overview&lt;/h2>
&lt;p>Grafana Enterprise Metrics provides the ability to understand the cardinality of your metrics and labels using &lt;a href="#dashboards">Cardinality analysis dashboards&lt;/a>
that are shipped with the Grafana Enterprise Metrics plugin or via an &lt;a href="#http-api">API&lt;/a>.&lt;/p></description></item><item><title>Using tenant federation</title><link>https://grafana.com/docs/enterprise-metrics/v2.1.x/tenant-management/tenant-federation/</link><pubDate>Fri, 03 Apr 2026 19:43:06 +0000</pubDate><guid>https://grafana.com/docs/enterprise-metrics/v2.1.x/tenant-management/tenant-federation/</guid><content><![CDATA[&lt;h2 id=&#34;overview&#34;&gt;Overview&lt;/h2&gt;
&lt;p&gt;GEM supports creating access policies that can span multiple tenants. Doing so enables viewers in Grafana Enterprise to view data coming from more than one tenant simultaneously.&lt;/p&gt;
&lt;p&gt;This page will cover the ability to query data from multiple tenants at once, as well as the ability to create alerting and recording rules that use data from multiple tenants at once.&lt;/p&gt;
&lt;h2 id=&#34;prerequisites&#34;&gt;Prerequisites&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;A configured Grafana Enterprise Metrics cluster. To create a GEM cluster,
refer to &lt;a href=&#34;../../setup/&#34;&gt;Set up GEM&lt;/a&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;This guide will assume there are two tenants: &lt;code&gt;team-engineering&lt;/code&gt; and
&lt;code&gt;team-finance&lt;/code&gt;. To create a tenant, refer to &lt;a href=&#34;../../set-up-gem-tenant/&#34;&gt;Set up a GEM tenant&lt;/a&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;cross-tenant-queries&#34;&gt;Cross-tenant queries&lt;/h2&gt;
&lt;h3 id=&#34;set-up-an-access-policy-with-tenant-federation-and-a-token&#34;&gt;Set up an access policy with tenant federation and a token&lt;/h3&gt;
&lt;p&gt;To allow queries to span both GEM tenants, which are for demonstration purposes named &lt;code&gt;team-engineering&lt;/code&gt; and &lt;code&gt;team-finance&lt;/code&gt;,
create a new access policy called &lt;code&gt;leadership&lt;/code&gt;. The necessary steps are:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Create a new access policy &lt;code&gt;leadership&lt;/code&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Enable the &lt;code&gt;metrics:read&lt;/code&gt; scope.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Add the tenants &lt;code&gt;team-engineering&lt;/code&gt; and &lt;code&gt;team-finance&lt;/code&gt;. Alternatively, you can add the special tenant name &lt;code&gt;*&lt;/code&gt; to create an access policy that has access to all tenants in the cluster.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Create a new token for the access-policy and store the token in your
clipboard:&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;





  
  
  


&lt;div&gt;
  &lt;iframe src=&#34;https://player.vimeo.com/video/742056367?transparent=0&#34; title=&#34;vimeo video&#34; webkitallowfullscreen=&#34;&#34; mozallowfullscreen=&#34;&#34; allowfullscreen=&#34;&#34;&gt;&lt;/iframe&gt;
  &lt;div &gt;
    
  &lt;/div&gt;
&lt;/div&gt;
&lt;h3 id=&#34;set-up-a-grafana-data-source-using-the-access-policy&#34;&gt;Set up a Grafana data source using the access policy&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Create a new Prometheus data source from the Grafana configuration menu.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Enter the URL of your GEM cluster, for example &lt;code&gt;http://enterprise-metrics/prometheus&lt;/code&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;From the &lt;strong&gt;Auth&lt;/strong&gt; section, enable Basic auth.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;In the &lt;strong&gt;User&lt;/strong&gt; field, enter: &lt;code&gt;team-engineering|team-finance&lt;/code&gt; where all the names of the tenants that you want to query across are separated by the &lt;code&gt;|&lt;/code&gt; pipe character.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;In the &lt;strong&gt;Password&lt;/strong&gt; field, paste the token created in the token creation
process.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Queries that are performed using this data source in either Explore or inside of
dashboards are performed across all of the tenants that you specified in the &lt;strong&gt;User&lt;/strong&gt;
field, and are processed as if all of the data were in a single tenant.&lt;/p&gt;
&lt;p&gt;To submit a query across all tenants that your access policy has access to, you can either:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Explicitly set the name of all the tenants separated by a pipe character &amp;ldquo;|&amp;rdquo; in the &lt;em&gt;username&lt;/em&gt;. For example, to query across &lt;code&gt;tenant1&lt;/code&gt;, &lt;code&gt;tenant2&lt;/code&gt;, and &lt;code&gt;tenant3&lt;/code&gt; you would enter &lt;code&gt;tenant1|tenant2|tenant3&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Set the username to a wildcard character &lt;code&gt;*&lt;/code&gt;. This will query all tenants that the access policy grants you access to, without requiring you to explicitly specify their names.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;When using an access policy that has a wildcard (&lt;code&gt;*&lt;/code&gt;) as the &lt;em&gt;username&lt;/em&gt;, you can query all tenants for that cluster by also specifying &lt;code&gt;*&lt;/code&gt; as the &lt;em&gt;username&lt;/em&gt; in your data source URL.&lt;/p&gt;
&lt;p&gt;Conversely, if you use a wildcard &lt;em&gt;username&lt;/em&gt; in your data source configuration with an access policy with specific tenants, that data source has access to only those tenants.&lt;/p&gt;





  
  
  


&lt;div&gt;
  &lt;iframe src=&#34;https://player.vimeo.com/video/742056367?transparent=0&#34; title=&#34;vimeo video&#34; webkitallowfullscreen=&#34;&#34; mozallowfullscreen=&#34;&#34; allowfullscreen=&#34;&#34;&gt;&lt;/iframe&gt;
  &lt;div &gt;
    
  &lt;/div&gt;
&lt;/div&gt;
&lt;h2 id=&#34;cross-tenant-alerting-and-recording-rules&#34;&gt;Cross-tenant alerting and recording rules&lt;/h2&gt;
&lt;p&gt;&lt;span style=&#34;background-color:#f3f973;&#34;&gt;Cross-tenant alerting and recording rules are an experimental feature.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;GEM supports alerting and recording rules that operate on data from multiple tenants.&lt;/p&gt;
&lt;p&gt;To create a federated alerting or recording rule, use the &lt;code&gt;source_tenants&lt;/code&gt; field when defining your rule group. This field defines which tenants the rule will read data from. Any rule in a group with a non-empty &lt;code&gt;source_tenants&lt;/code&gt; field is considered a federated rule.&lt;/p&gt;
&lt;p&gt;Using the same example tenants we defined above, we&amp;rsquo;ll create a federated rule group that evaluates data coming from tenants &lt;code&gt;team-engineering&lt;/code&gt; and &lt;code&gt;team-finance&lt;/code&gt;, and stores the resulting series in &lt;code&gt;team-engineering&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;First, create your rule and rule group in a file called &lt;code&gt;payload.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;name: example
interval: 5m
source_tenants: [team-engineering, team-finance]
rules:
  - record: job:http_inprogress_requests:sum
    expr: sum by (job) (http_inprogress_requests)&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;This example recording rule is calculating a sum of &lt;code&gt;http_inprogress_requests&lt;/code&gt; by job every 5 minutes. Because the source tenants are &lt;code&gt;team-engineering&lt;/code&gt; and &lt;code&gt;team-finance&lt;/code&gt;, GEM will use all series with metric name &lt;code&gt;http_inprogress_requests&lt;/code&gt; in both of these tenants when calculating the sum.&lt;/p&gt;
&lt;p&gt;To create the cross-tenant rule group, use the curl command shown below, which uses the &lt;code&gt;Set rule group&lt;/code&gt; API endpoint and passes in the &lt;code&gt;payload.yaml&lt;/code&gt; we defined above:&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;sh&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-sh&#34;&gt;curl -u team-engineering:$API_TOKEN -X POST http://enterprise-metrics/api/v1/rules/fed-rule-group --data-binary &amp;#34;@/payload.yaml&amp;#34;&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;The username used in the curl call is what dictates where the output of the rule will be stored. In our example above, the output of the rule will be stored in &lt;code&gt;team-engineering&lt;/code&gt; because we have &lt;code&gt;-u team-engineering&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;The access policy to which the API token belongs must have &lt;code&gt;metrics:read&lt;/code&gt; and &lt;code&gt;rules:write&lt;/code&gt; scopes and apply to all of the tenants in &lt;code&gt;source_tenants&lt;/code&gt; (&lt;code&gt;team-engineering&lt;/code&gt; and &lt;code&gt;team-finance&lt;/code&gt; in our example) and the owning tenant (&lt;code&gt;team-engineering&lt;/code&gt; in our example). Otherwise, an HTTP unauthorized status (401) will be returned and the rule group will not be created.&lt;/p&gt;
&lt;p&gt;When the access policy used to create the federated rule group is deleted or updated to remove the &lt;code&gt;metrics:read&lt;/code&gt; scope or to remove any of the &lt;code&gt;source_tenants&lt;/code&gt;, that rule group will stop evaluating at the next rules synchronization. The synchronization interval is set by the &lt;code&gt;-ruler.poll-interval&lt;/code&gt; configuration parameter. By default, this is 1 minute.&lt;/p&gt;
&lt;p&gt;You can find more details about cross-tenant rules in the &lt;a href=&#34;/docs/mimir/latest/operators-guide/reference-http-api/#set-rule-group&#34;&gt;Grafana Mimir API documentation&lt;/a&gt;.&lt;/p&gt;
]]></content><description>&lt;h2 id="overview">Overview&lt;/h2>
&lt;p>GEM supports creating access policies that can span multiple tenants. Doing so enables viewers in Grafana Enterprise to view data coming from more than one tenant simultaneously.&lt;/p></description></item></channel></rss>