<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Manage Tempo on Grafana Labs</title><link>https://grafana.com/docs/tempo/v2.10.x/operations/</link><description>Recent content in Manage Tempo on Grafana Labs</description><generator>Hugo -- gohugo.io</generator><language>en</language><atom:link href="/docs/tempo/v2.10.x/operations/index.xml" rel="self" type="application/rss+xml"/><item><title>Monitor Tempo</title><link>https://grafana.com/docs/tempo/v2.10.x/operations/monitor/</link><pubDate>Thu, 09 Apr 2026 14:59:14 +0000</pubDate><guid>https://grafana.com/docs/tempo/v2.10.x/operations/monitor/</guid><content><![CDATA[&lt;h1 id=&#34;monitor-tempo&#34;&gt;Monitor Tempo&lt;/h1&gt;
&lt;p&gt;Tempo is instrumented to expose metrics, logs, and traces.
Furthermore, the Tempo repository has a &lt;a href=&#34;https://github.com/grafana/tempo/tree/main/operations/tempo-mixin&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;mixin&lt;/a&gt; that includes a
set of dashboards, rules, and alerts.
Together, these can be used to monitor Tempo in production.&lt;/p&gt;
&lt;h2 id=&#34;instrumentation&#34;&gt;Instrumentation&lt;/h2&gt;
&lt;p&gt;Metrics, logs, and traces from Tempo can be collected to observe its services and functions.&lt;/p&gt;
&lt;h3 id=&#34;metrics&#34;&gt;Metrics&lt;/h3&gt;
&lt;p&gt;Tempo is instrumented with &lt;a href=&#34;https://prometheus.io/&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;Prometheus metrics&lt;/a&gt; and emits RED metrics for most services and backends.
RED metrics are a standardized format for monitoring microservices, where R stands for requests, E stands for errors, and D stands for duration.&lt;/p&gt;
&lt;p&gt;The &lt;a href=&#34;#dashboards&#34;&gt;Tempo mixin&lt;/a&gt; provides several dashboards using these metrics.&lt;/p&gt;
&lt;h4 id=&#34;query-frontend-inspected-bytes&#34;&gt;Query frontend inspected bytes&lt;/h4&gt;
&lt;p&gt;Use &lt;code&gt;tempo_query_frontend_bytes_inspected_total&lt;/code&gt; to monitor how many bytes the query frontend reads from disk and object storage.
This counter is emitted per &lt;code&gt;tenant&lt;/code&gt; and &lt;code&gt;op&lt;/code&gt; (&lt;code&gt;traces&lt;/code&gt;, &lt;code&gt;search&lt;/code&gt;, &lt;code&gt;metadata&lt;/code&gt;, &lt;code&gt;metrics&lt;/code&gt;).
Because cached responses from queriers are excluded, it reflects actual storage and network I/O.&lt;/p&gt;
&lt;p&gt;For PromQL examples and alerting guidance, refer to 
    &lt;a href=&#34;/docs/tempo/v2.10.x/operations/monitor/query-io-and-timestamp-distance/&#34;&gt;Query query IO and time stamp distance&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&#34;logs&#34;&gt;Logs&lt;/h3&gt;
&lt;p&gt;Tempo emits logs in the &lt;code&gt;key=value&lt;/code&gt; (&lt;a href=&#34;https://brandur.org/logfmt&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;logfmt&lt;/a&gt;) format.&lt;/p&gt;
&lt;h3 id=&#34;traces&#34;&gt;Traces&lt;/h3&gt;
&lt;p&gt;Tempo uses the &lt;a href=&#34;https://github.com/open-telemetry/opentelemetry-go&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;OpenTelemetry SDK&lt;/a&gt; for tracing instrumentation.
The complete read path and some parts of the write path of Tempo are instrumented for tracing.&lt;/p&gt;
&lt;p&gt;You can configure the tracer &lt;a href=&#34;https://opentelemetry.io/docs/languages/sdk-configuration/otlp-exporter/&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;using environment variables&lt;/a&gt;.
To enable tracing, set one of the following: &lt;code&gt;OTEL_EXPORTER_OTLP_ENDPOINT&lt;/code&gt; or &lt;code&gt;OTEL_EXPORTER_OTLP_TRACES_ENDPOINT&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;The OpenTelemetry SDK uses OTLP/HTTP by default, which can be configured with &lt;code&gt;OTEL_EXPORTER_OTLP_PROTOCOL&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id=&#34;polling&#34;&gt;Polling&lt;/h2&gt;
&lt;p&gt;Tempo maintains knowledge of the state of the backend by polling it on regular intervals.
There are currently only two components that need this knowledge and, consequently, only two that poll the backend: compactors and queriers.&lt;/p&gt;
&lt;p&gt;Refer to &lt;a href=&#34;polling/&#34;&gt;Use polling to monitor the backend status&lt;/a&gt; for Tempo.&lt;/p&gt;
&lt;h2 id=&#34;dashboards&#34;&gt;Dashboards&lt;/h2&gt;
&lt;p&gt;The &lt;a href=&#34;https://github.com/grafana/tempo/tree/main/operations/tempo-mixin&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;Tempo mixin&lt;/a&gt; has four Grafana dashboards in the &lt;code&gt;yamls&lt;/code&gt; folder that you can download and import into your Grafana UI.
These dashboards work well when you run Tempo in a Kubernetes (k8s) environment and metrics scraped have the
&lt;code&gt;cluster&lt;/code&gt; and &lt;code&gt;namespace&lt;/code&gt; labels.&lt;/p&gt;
&lt;h3 id=&#34;tempo-reads-dashboard&#34;&gt;Tempo Reads dashboard&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;This is available as &lt;code&gt;tempo-reads.json&lt;/code&gt;.&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;The Reads dashboard gives information on Requests, Errors, and Duration (RED) on the query path of Tempo.
Each query touches the Gateway, Tempo-Query, Query-Frontend, Queriers, Ingesters, the backend, and Cache, if present.&lt;/p&gt;
&lt;p&gt;Use this dashboard to monitor the performance of each of the mentioned components and to decide the number of
replicas in each deployment.&lt;/p&gt;
&lt;h3 id=&#34;tempo-writes-dashboard&#34;&gt;Tempo Writes dashboard&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;This is available as &lt;code&gt;tempo-writes.json&lt;/code&gt;.&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;The Writes dashboard gives information on RED on the write/ingest path of Tempo.
A write query touches the Gateway, Distributors, Ingesters, and the backend.
This dashboard also gives information
on the number of operations performed by the Compactor to the backend.&lt;/p&gt;
&lt;p&gt;Use this dashboard to monitor the performance of each of the mentioned components and to decide the number of
replicas in each deployment.&lt;/p&gt;
&lt;h3 id=&#34;tempo-resources-dashboard&#34;&gt;Tempo Resources dashboard&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;This is available as &lt;code&gt;tempo-resources.json&lt;/code&gt;.&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;The Resources dashboard provides information on &lt;code&gt;CPU&lt;/code&gt;, &lt;code&gt;Container Memory&lt;/code&gt;, and &lt;code&gt;Go Heap Inuse&lt;/code&gt;.
This dashboard is useful for resource provisioning for the different Tempo components.&lt;/p&gt;
&lt;p&gt;Use this dashboard to see if any components are running close to their assigned limits.&lt;/p&gt;
&lt;h3 id=&#34;tempo-operational-dashboard&#34;&gt;Tempo Operational dashboard&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;This is available as &lt;code&gt;tempo-operational.json&lt;/code&gt;.&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;The Tempo Operational dashboard deserves special mention because it is probably a stack of dashboard anti-patterns.
It&amp;rsquo;s big and complex, doesn&amp;rsquo;t use &lt;code&gt;jsonnet&lt;/code&gt;, and displays far too many metrics in one place.
For just getting started, the RED dashboards are great places to learn how to monitor Tempo in an opaque way.&lt;/p&gt;
&lt;p&gt;This dashboard is included in the Tempo repository for two reasons:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The dashboard provides a stack of metrics for other operators to consider monitoring while running Tempo.&lt;/li&gt;
&lt;li&gt;We want the dashboard in our internal infrastructure and we vendor the &lt;code&gt;tempo-mixin&lt;/code&gt; to do this.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;rules-and-alerts&#34;&gt;Rules and alerts&lt;/h2&gt;
&lt;p&gt;The Rules and Alerts are available as &lt;a href=&#34;https://github.com/grafana/tempo/tree/main/operations/tempo-mixin-compiled&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;YAML files in the compiled mixin&lt;/a&gt; on the repository.&lt;/p&gt;
&lt;p&gt;To set up alerting, download the provided JSON files and configure them for use on your Prometheus monitoring server.&lt;/p&gt;
&lt;p&gt;Check the &lt;a href=&#34;https://github.com/grafana/tempo/blob/main/operations/tempo-mixin/runbook.md&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;runbook&lt;/a&gt; to understand the
various steps that can be taken to fix firing alerts.&lt;/p&gt;
]]></content><description>&lt;h1 id="monitor-tempo">Monitor Tempo&lt;/h1>
&lt;p>Tempo is instrumented to expose metrics, logs, and traces.
Furthermore, the Tempo repository has a &lt;a href="https://github.com/grafana/tempo/tree/main/operations/tempo-mixin" target="_blank" rel="noopener noreferrer">mixin&lt;/a> that includes a
set of dashboards, rules, and alerts.
Together, these can be used to monitor Tempo in production.&lt;/p></description></item><item><title>Dedicated attribute columns</title><link>https://grafana.com/docs/tempo/v2.10.x/operations/dedicated_columns/</link><pubDate>Thu, 09 Apr 2026 14:59:14 +0000</pubDate><guid>https://grafana.com/docs/tempo/v2.10.x/operations/dedicated_columns/</guid><content><![CDATA[&lt;h1 id=&#34;dedicated-attribute-columns&#34;&gt;Dedicated attribute columns&lt;/h1&gt;
&lt;p&gt;Dedicated attribute columns improve query performance by storing the most frequently used attributes in their own columns,
rather than in the generic attribute key-value list.&lt;/p&gt;
&lt;p&gt;Introduced with &lt;code&gt;vParquet3&lt;/code&gt;, dedicated attribute columns are available when using &lt;code&gt;vParquet3&lt;/code&gt; or later storage formats.
Even though &lt;code&gt;vParquet3&lt;/code&gt; is deprecated, this feature is available when using the current value of &lt;code&gt;vParquet4&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;With &lt;code&gt;vParquet5&lt;/code&gt;, dedicated attribute columns gain support for array-valued attributes, event-scoped attributes, and blob attributes using the &lt;code&gt;options&lt;/code&gt; field.&lt;/p&gt;
&lt;h2 id=&#34;configuration&#34;&gt;Configuration&lt;/h2&gt;
&lt;p&gt;You can configure dedicated attribute columns in the storage block or via overrides.&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;# Storage configuration for traces
storage:
  trace:
    block:
      # Default dedicated columns for all blocks
      parquet_dedicated_columns:
        - name: &amp;lt;string&amp;gt; # name of the attribute
          type: &amp;lt;string&amp;gt; # type of the attribute. options: string, int
          scope: &amp;lt;string&amp;gt; # scope of the attribute. options: resource, span, event
          options: [&amp;lt;string&amp;gt;] # optional, vParquet5 only. options: array, blob

overrides:
  # Global overrides for dedicated columns configuration
  parquet_dedicated_columns:
    - name: &amp;lt;string&amp;gt; # name of the attribute
      type: &amp;lt;string&amp;gt; # type of the attribute. options: string, int
      scope: &amp;lt;string&amp;gt; # scope of the attribute. options: resource, span, event
      options: [&amp;lt;string&amp;gt;] # optional, vParquet5 only. options: array, blob

  per_tenant_override_config: /conf/overrides.yaml
---
# /conf/overrides.yaml
# Tenant-specific overrides configuration
overrides:
  &amp;#34;&amp;lt;tenant id&amp;gt;&amp;#34;:
    parquet_dedicated_columns:
      - name: &amp;lt;string&amp;gt; # name of the attribute
        type: &amp;lt;string&amp;gt; # type of the attribute. options: string, int
        scope: &amp;lt;string&amp;gt; # scope of the attribute. options: resource, span, event
        options: [&amp;lt;string&amp;gt;] # optional, vParquet5 only. options: array, blob

  # A &amp;#34;wildcard&amp;#34; override can be used that will apply to all tenants if a match is not found.
  &amp;#34;*&amp;#34;:
    parquet_dedicated_columns:
      - name: &amp;lt;string&amp;gt; # name of the attribute
        type: &amp;lt;string&amp;gt; # type of the attribute. options: string, int
        scope: &amp;lt;string&amp;gt; # scope of the attribute. options: resource, span, event
        options: [&amp;lt;string&amp;gt;] # optional, vParquet5 only. options: array, blob&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Priority is given to the most specific configuration, so tenant-specific overrides will take precedence over global overrides.
Similarly, default overrides take precedence over storage block configuration.&lt;/p&gt;
&lt;h2 id=&#34;usage&#34;&gt;Usage&lt;/h2&gt;
&lt;p&gt;Dedicated attribute columns are limited to 10 string attributes and 5 integer attributes per scope (span, resource, and event).
As a rule of thumb, good candidates for dedicated attribute columns are attributes that contribute the most to the block size,
even if they aren&amp;rsquo;t frequently queried.
Reducing the generic attribute key-value list size significantly improves query performance.&lt;/p&gt;
&lt;h3 id=&#34;integer-attribute-selection&#34;&gt;Integer attribute selection&lt;/h3&gt;
&lt;p&gt;Integer dedicated columns are most effective when the attribute is present on at least 5% of rows in a scope.
The &lt;code&gt;tempo-cli analyse block&lt;/code&gt; command shows the percentage of rows for each integer attribute and marks candidates that meet this threshold with a recommendation.
Sparse integer attributes (below 5% prevalence) typically perform better in the generic attribute storage.&lt;/p&gt;
&lt;h3 id=&#34;array-valued-attributes&#34;&gt;Array-valued attributes&lt;/h3&gt;
&lt;p&gt;Dedicated attribute columns support array-valued attributes.
This is useful for attributes that can have multiple values, such as HTTP headers or custom tags.&lt;/p&gt;
&lt;p&gt;To enable array support, add &lt;code&gt;options: [&amp;quot;array&amp;quot;]&lt;/code&gt; to the dedicated attribute column configuration.
The &lt;code&gt;options&lt;/code&gt; field is only available in &lt;code&gt;vParquet5&lt;/code&gt; and later.
Earlier versions ignore this field and only support single-valued attributes.&lt;/p&gt;
&lt;p&gt;When &lt;code&gt;options: [&amp;quot;array&amp;quot;]&lt;/code&gt; is set, the dedicated column stores multiple values per attribute.
Without this option (default), only single values are supported.&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;storage:
  trace:
    block:
      version: vParquet5
      parquet_dedicated_columns:
        # Single-valued string attribute (default behavior)
        - name: http.method
          type: string
          scope: span

        # Array-valued string attribute
        - name: http.request.header.accept
          type: string
          scope: span
          options: [&amp;#34;array&amp;#34;]

        # Array-valued integer attribute
        - name: custom.retry.counts
          type: int
          scope: span
          options: [&amp;#34;array&amp;#34;]&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;h3 id=&#34;blob-attributes&#34;&gt;Blob attributes&lt;/h3&gt;
&lt;p&gt;Blob attributes are designed for high-cardinality or high-length string values where dictionary encoding becomes inefficient.
Examples include UUIDs, stack traces, request bodies, or any attribute with many unique values.&lt;/p&gt;
&lt;p&gt;When an attribute&amp;rsquo;s dictionary size per row group exceeds a threshold (default 4MiB), the column should be marked as a blob.
The &lt;code&gt;tempo-cli analyse block&lt;/code&gt; command can help identify blob candidates by showing the estimated dictionary size per row group.&lt;/p&gt;
&lt;p&gt;To enable blob mode, add &lt;code&gt;options: [&amp;quot;blob&amp;quot;]&lt;/code&gt; to the dedicated attribute column configuration.
Blob columns use &lt;code&gt;zstd&lt;/code&gt; compression instead of dictionary encoding, which is more efficient for high-cardinality data.&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;storage:
  trace:
    block:
      version: vParquet5
      parquet_dedicated_columns:
        # Standard dedicated column (uses dictionary encoding)
        - name: http.method
          type: string
          scope: span

        # Blob column for high-cardinality data
        - name: db.statement
          type: string
          scope: span
          options: [&amp;#34;blob&amp;#34;]

        # Blob column for stack traces
        - name: exception.stacktrace
          type: string
          scope: event
          options: [&amp;#34;blob&amp;#34;]&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Use the &lt;code&gt;tempo-cli analyse block&lt;/code&gt; command with the &lt;code&gt;--blob-threshold&lt;/code&gt; option to identify attributes that should be configured as blobs.
Attributes exceeding the threshold are marked as &amp;ldquo;(blob)&amp;rdquo; in the output.&lt;/p&gt;
&lt;h3 id=&#34;event-scoped-attributes&#34;&gt;Event-scoped attributes&lt;/h3&gt;
&lt;p&gt;With &lt;code&gt;vParquet5&lt;/code&gt;, dedicated columns support event-scoped attributes in addition to span and resource scopes.
Event-scoped columns are useful for frequently queried event attributes such as exception details or custom event data.&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;storage:
  trace:
    block:
      version: vParquet5
      parquet_dedicated_columns:
        # Event-scoped string attribute
        - name: exception.message
          type: string
          scope: event

        # Event-scoped attribute with blob option
        - name: exception.stacktrace
          type: string
          scope: event
          options: [&amp;#34;blob&amp;#34;]&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;h3 id=&#34;tempo-cli&#34;&gt;Tempo-cli&lt;/h3&gt;
&lt;p&gt;You can use the &lt;code&gt;tempo-cli&lt;/code&gt; tool to find good candidates for dedicated attribute columns.
The &lt;code&gt;tempo-cli&lt;/code&gt; provides the commands &lt;code&gt;analyse block &amp;lt;tenant-id&amp;gt; &amp;lt;block-id&amp;gt;&lt;/code&gt; and &lt;code&gt;analyse blocks &amp;lt;tenant-id&amp;gt;&lt;/code&gt; that will output the
top N attributes by size for a given block or all blocks in a tenant.&lt;/p&gt;
&lt;p&gt;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;Bash&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-bash&#34;&gt;tempo-cli analyse blocks --backend=local --bucket=./cmd/tempo-cli/test-data/ single-tenant&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Refer to the &lt;a href=&#34;../tempo_cli/&#34;&gt;tempo-cli documentation&lt;/a&gt; for more information.&lt;/p&gt;
]]></content><description>&lt;h1 id="dedicated-attribute-columns">Dedicated attribute columns&lt;/h1>
&lt;p>Dedicated attribute columns improve query performance by storing the most frequently used attributes in their own columns,
rather than in the generic attribute key-value list.&lt;/p></description></item><item><title>Tune search performance</title><link>https://grafana.com/docs/tempo/v2.10.x/operations/backend_search/</link><pubDate>Thu, 09 Apr 2026 14:59:14 +0000</pubDate><guid>https://grafana.com/docs/tempo/v2.10.x/operations/backend_search/</guid><content><![CDATA[&lt;h1 id=&#34;tune-search-performance&#34;&gt;Tune search performance&lt;/h1&gt;
&lt;p&gt;Regardless of whether or not you are using TraceQL or the original search API, Tempo searches all of the blocks
in the specified time range.
Depending on your volume, this may result in slow queries.&lt;/p&gt;
&lt;p&gt;This document explains how read path in Tempo works, what controls you have to tune the read path, details of the core configuration options, and how to tune these configuration options to get the most out of your Tempo cluster.&lt;/p&gt;
&lt;p&gt;The general advice is to scale your compactors and queriers. Additional queriers can more effectively run jobs in parallel
while additional compactors more aggressively reduce the length of your blocklist and copies of data (if using &lt;code&gt;RF=3&lt;/code&gt;).&lt;/p&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;All forms of search (TraceQL and tags based) are only supported on the &lt;code&gt;vParquet&lt;/code&gt; and forward blocks. &lt;a href=&#34;../../configuration/parquet/#choose-a-different-block-format&#34;&gt;v2 blocks&lt;/a&gt;
can only be used for trace by id lookup.&lt;/p&gt;
&lt;p&gt;Tempo 2.3 and higher support &lt;a href=&#34;../dedicated_columns/&#34;&gt;Dedicated attribute columns&lt;/a&gt;, another great method to improve search performance.&lt;/p&gt;&lt;/blockquote&gt;&lt;/div&gt;

&lt;h2 id=&#34;before-you-begin&#34;&gt;Before you begin&lt;/h2&gt;
&lt;p&gt;You should understand the basic Tempo architecture.&lt;/p&gt;
&lt;p&gt;For more information, refer to the &lt;a href=&#34;/docs/tempo/latest/operations/architecture/#query-frontend&#34;&gt;Tempo architecture&lt;/a&gt; to learn about how Tempo works.&lt;/p&gt;
&lt;h3 id=&#34;glossary&#34;&gt;Glossary&lt;/h3&gt;
&lt;dl&gt;
&lt;dt&gt;query&lt;/dt&gt;
&lt;dd&gt;A search query, issued by end user. For example, &lt;code&gt;{ traceDuration &amp;gt; 1s }&lt;/code&gt; is a TraceQL query.&lt;/dd&gt;
&lt;dt&gt;job&lt;/dt&gt;
&lt;dd&gt;A shard of a search query, the lowest unit of work. A query is broken down into multiple jobs and processed.&lt;/dd&gt;
&lt;dt&gt;batch&lt;/dt&gt;
&lt;dd&gt;A group of jobs is called a batch.&lt;/dd&gt;
&lt;dt&gt;frontend&lt;/dt&gt;
&lt;dd&gt;Another name for query-frontend&lt;/dd&gt;
&lt;dt&gt;querier&lt;/dt&gt;
&lt;dd&gt;Responsible for executing (processing) the jobs, and sending the results back to query-frontend.&lt;/dd&gt;
&lt;/dl&gt;
&lt;h2 id=&#34;tempo-query-path&#34;&gt;Tempo query path&lt;/h2&gt;
&lt;p&gt;Tempo has a query path made up of a query-frontend, querrier, ingester, metrics-generator, and backend.&lt;/p&gt;
&lt;p&gt;You can think about each component in a query path as a generic producer and worker model:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The query-frontend is a producer and it has multiple workers connected to it. The query-frontend takes a single query and shards it into multiple jobs (units of work).&lt;/li&gt;
&lt;li&gt;The queriers are workers. They enqueue work from a queue, process it, and send the results back to the producer (query-frontend).&lt;/li&gt;
&lt;li&gt;The querier either reads data from backend and processes the query, or it delegates the query to ingesters and metrics generators based on the type of job, time range, and query type.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img
  class=&#34;lazyload d-inline-block&#34;
  data-src=&#34;/media/docs/tempo/tempo-query-frontend.svg&#34;
  alt=&#34;Tempo query path architecture&#34;/&gt;&lt;/p&gt;
&lt;h3 id=&#34;lifecycle-of-a-query&#34;&gt;Lifecycle of a query&lt;/h3&gt;
&lt;p&gt;A search request comes from the user, and it is split into multiple jobs in the query-frontend.&lt;/p&gt;
&lt;p&gt;These jobs are then added to a queue and queriers pick up jobs in batches to process.&lt;/p&gt;
&lt;p&gt;A single search query can create hundreds of jobs based on the time range and other variables.
These jobs are batched and sent to queriers.&lt;/p&gt;
&lt;p&gt;The querier receives the batch and processes the jobs in the batch, builds results, and sends the results of the whole batch back to the query-frontend.&lt;/p&gt;
&lt;p&gt;The query-frontend merges and deduplicates the results, and sends them back to the client.&lt;/p&gt;
&lt;p&gt;When querier starts, it opens multiple connections to each query-frontend.&lt;/p&gt;
&lt;p&gt;Job batches are sent over these connections, and return the results.
This process is synchronized so a single job batch can block a connection.&lt;/p&gt;
&lt;p&gt;The number of connections control the number of batches a querier processes concurrently.
The number of connections is controlled by &lt;code&gt;querier.max_concurrent_queries&lt;/code&gt; OR &lt;code&gt;frontend_worker.parallelism&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id=&#34;general-guidelines&#34;&gt;General guidelines&lt;/h2&gt;
&lt;p&gt;Tuning the search pipeline can be difficult as it requires balancing a number of different configuration parameters. The below tips
can you get your head around the general problem, but the specifics require experimentation.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Review the query-frontend logs for lines like the following to get a feeling for how many jobs your queries are creating:&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;level=info ts=2023-07-19T19:38:01.354220385Z caller=searchsharding.go:236 msg=&amp;#34;sharded search query request stats and SearchMetrics&amp;#34; ...&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;For a single TraceQL query the maximum number of parallel jobs is constrained by:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;query_frontend.search.concurrent_jobs&lt;/code&gt;: This is the maximum number of jobs the frontend dispatches for one TraceQL query.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;# queriers * querier.max_concurrent_queries * query_frontend.max_batch_size&lt;/code&gt;: This is the maximum job capacity of your Tempo cluster.
If a given TraceQL query produces less jobs then these two values it should be executed entirely in parallel on the queriers.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Increasing &lt;code&gt;querier.max_concurrent_queries&lt;/code&gt; is a great way to get more out of your queriers. However, if queriers are OOMing or saturating other
resources then this should be lowered. Lowering &lt;code&gt;query_frontend.max_batch_size&lt;/code&gt; will also reduce the total work attempted by one querier.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;querier-and-query-frontend-configuration&#34;&gt;Querier and query-frontend configuration&lt;/h2&gt;
&lt;p&gt;Queriers and query-frontends have additional configuration related to search of the backend datastore.&lt;/p&gt;
&lt;h3 id=&#34;querier&#34;&gt;Querier&lt;/h3&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;querier:
  # Control the amount of work each querier will attempt. The total number of
  # jobs a querier will attempt this is this value * query_frontend.max_batch_size
  max_concurrent_queries: 20&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;h3 id=&#34;query-frontend&#34;&gt;Query-frontend&lt;/h3&gt;
&lt;p&gt;&lt;a href=&#34;../../configuration/#query-frontend&#34;&gt;Query frontend&lt;/a&gt; lists all configuration
options.&lt;/p&gt;
&lt;p&gt;These suggestions help deal with scaling issues.&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;server:
  # At larger scales, searching starts to feel more like a batch job.
  # Increase the server timeout intervals.
  http_server_read_timeout: 2m
  http_server_write_timeout: 2m

query_frontend:
  # When increasing concurrent_jobs, also increase the queue size per tenant,
  # or search requests will be cause 429 errors. This is the total number of jobs
  # per tenant allowed in the queue.
  max_outstanding_per_tenant: 2000

  # The number of jobs the query-frontend will batch together when passing jobs to the queriers. This value
  # This value * querier.max_concurrent_queries is your the max number of jobs a given querier will try at once.
  max_batch_size: 3

  search:
    # At larger scales, increase the number of jobs attempted simultaneously,
    # per search query.
    concurrent_jobs: 2000

    # The query-frontend will attempt to divide jobs up by an estimate of job size. The smallest possible
    # job size is a single parquet row group. Increasing this value will create fewer, larger jobs. Decreasing
    # it will create more, smaller jobs.
    target_bytes_per_job: 50_000_000&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;h2 id=&#34;settings-that-are-safe-to-increase-without-major-impact&#34;&gt;Settings that are safe to increase without major impact.&lt;/h2&gt;
&lt;p&gt;Scaling up queriers is a safe way to add more query capacity.
At Grafana Labs, we prefer to scale queries horizontally by adding more replicas.
If you see out of memory (OOM) errors, it might be worth scaling the queriers vertically.&lt;/p&gt;
&lt;p&gt;We recommend running at least two replicates of query-frontend. These replicas should be scaled vertically instead of horizontally.
If you need to scale, scale query-frontends vertically by adding more CPU and RAM.
Currently, query-frontends aren’t scaled horizontally, but this might change in the future.&lt;/p&gt;
&lt;p&gt;The reason we keep only two replicas is because each query-frontend has its own request queue and it also impacts the amount of jobs sent to each querier.
If you add more query-frontends, you need to tune other configuration parameters to account for the change.
We decided to keep query-frontend to two replicas for now.&lt;/p&gt;
&lt;p&gt;In a dedicated cluster, you can increase &lt;code&gt;query_frontend.max_outstanding_per_tenant&lt;/code&gt; because the cluster is dedicated to a single customer.
In a shared cluster, you need to use more caution when increasing &lt;code&gt;querier.max_outstanding_per_tenant&lt;/code&gt;&lt;/p&gt;
&lt;h3 id=&#34;parameter-interactions&#34;&gt;Parameter interactions&lt;/h3&gt;
&lt;p&gt;The &lt;code&gt;query_frontend&lt;/code&gt; configuration options control how Tempo shards a query into multiple jobs.
These options also control the size of a single job, number of jobs, and the number of jobs added to the work queue at once (concurrently) for queriers to be picked up.
The &lt;code&gt;max_batch_size&lt;/code&gt; option controls how many jobs are sent to queriers at once in a single batch.&lt;/p&gt;
&lt;p&gt;Querier configuration options control processing of these jobs, queries operate at a job level.
They&amp;rsquo;re workers: they pick a job from the queue and execute the job, and return the results back to the query-frontend.
Querier options control how many jobs it processes at once by opening concurrent connections to query-frontends, and each connection processes a single.&lt;/p&gt;
&lt;h2 id=&#34;guidelines-on-key-configuration-parameters&#34;&gt;Guidelines on key configuration parameters&lt;/h2&gt;
&lt;p&gt;The following sections provide recommendations for key configuration parameters.&lt;/p&gt;
&lt;h3 id=&#34;query_frontendmax_outstanding_per_tenant-parameter&#34;&gt;&lt;code&gt;query_frontend.max_outstanding_per_tenant&lt;/code&gt; parameter&lt;/h3&gt;
&lt;p&gt;The &lt;code&gt;query_frontend.max_outstanding_per_tenant&lt;/code&gt; parameter decides the maximum number of outstanding requests per tenant per frontend; requests beyond this error with HTTP &lt;code&gt;429&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;This configuration controls how much load a single tenant can put on a cluster. A return of &lt;code&gt;429&lt;/code&gt; indicates users to slow down.&lt;/p&gt;
&lt;p&gt;This configuration can be used to maintain quality of service (QoS) for tenants by asking tenants to slow down by sending &lt;code&gt;429&lt;/code&gt; to the tenant that&amp;rsquo;s overloading the system.&lt;/p&gt;
&lt;h4 id=&#34;guidelines&#34;&gt;Guidelines&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;In a dedicated cluster with one big tenant, it’s okay to increase the number for &lt;code&gt;query_frontend.max_outstanding_per_tenant.&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;In a shared cluster with a lot of small tenants, keep the number small.&lt;/li&gt;
&lt;li&gt;If a single tenant is overwhelming the whole cluster, you should decrease this parameter. It reduces the amount of work the tenant can enqueue at once. It starts returning &lt;code&gt;429&lt;/code&gt; to the tenant.&lt;/li&gt;
&lt;li&gt;If your tenants are complaining about getting &lt;code&gt;429&lt;/code&gt;, you might want to increase this parameter and scale out queries to handle the query load.&lt;/li&gt;
&lt;li&gt;If you increase other configurations that increase the query throughput or scale queriers, you might want to reduce this parameter to control the amount of work that can be enqueued.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;query_frontendmax_batch_size-parameter&#34;&gt;&lt;code&gt;query_frontend.max_batch_size&lt;/code&gt; parameter&lt;/h3&gt;
&lt;p&gt;The number of jobs to batch together in one HTTP request to the querier.
Large search queries over a longer time range produce thousands of jobs.
Instead of sending jobs one by one, batch the jobs and send them at once.
The querier picks up and process them.&lt;/p&gt;
&lt;p&gt;Batching pushes jobs faster to the queriers, and reduce the time spent waiting around for jobs to be picked up by the querier.&lt;/p&gt;
&lt;h4 id=&#34;guidelines-1&#34;&gt;Guidelines&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;Default value of &lt;code&gt;max_batch_size&lt;/code&gt; is set to &lt;code&gt;7&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;We DO NOT recommend changing the batch size from the default value of &lt;code&gt;7&lt;/code&gt;. Based on testing at Grafana Labs, &lt;code&gt;7&lt;/code&gt; is a good default.&lt;/li&gt;
&lt;li&gt;If the batch size is big, you push more jobs at once but it takes longer for the querier to process the batch and return the results back.&lt;/li&gt;
&lt;li&gt;Big batch size will increase the latency of the querier requests, and they might start hitting timeouts of 5xx, which will increase the rate of retries.&lt;/li&gt;
&lt;li&gt;Bigger &lt;code&gt;max_batch_size&lt;/code&gt; results in pushing too many jobs to the queriers. The jobs then have to be canceled if a query is exited early.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;query_frontendsearchconcurrent_jobs-parameter&#34;&gt;&lt;code&gt;query_frontend.search.concurrent_jobs&lt;/code&gt; parameter&lt;/h3&gt;
&lt;p&gt;The number of concurrent jobs to execute when searching the backend. This controls how much work is produced concurrently.&lt;/p&gt;
&lt;p&gt;To put it another way, if a search job is sharded into 5000 jobs, and &lt;code&gt;concurrent_jobs&lt;/code&gt; is set to 1000, then Tempo only executes 1000 jobs concurrently.
The other 4000 jobs are processed one by one as the first 1000 jobs return the responses.&lt;/p&gt;
&lt;p&gt;If Tempo manages to answer the search query without executing all 5000 jobs, Tempo exits early and cancels the jobs that weren&amp;rsquo;t started.&lt;/p&gt;
&lt;h4 id=&#34;guidelines-2&#34;&gt;Guidelines&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;This params controls the numbers of concurrent jobs to the number of jobs to put in the queue at once for processing a query.&lt;/li&gt;
&lt;li&gt;If this number is low, big queries that create lots of jobs processed slowly.&lt;/li&gt;
&lt;li&gt;If this number is high, the frontend pushes work faster to queries, and the frontend needs to cancel those jobs if the search exits early because the query is fulfilled.&lt;/li&gt;
&lt;li&gt;If you see high load, spikes, or OOMs in the queriers, you can lower this configuration for a fair QoS and stability.&lt;/li&gt;
&lt;li&gt;Having this number to a high value will allow a single tenant to push lots of work at once and overwhelm the querier. So keeping it to a lower number in a shared cluster allows for fair scheduling.&lt;/li&gt;
&lt;li&gt;This parameter controls how fast jobs are pushed into the queue for queries to be picked up by queries&lt;/li&gt;
&lt;li&gt;Adjusting this can impact your batch size so that metric should be watched while making changes to this configuration, and make sure that actual batch size is around the &lt;code&gt;max_batch_size&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;We recommend keeping it high in dedicated clusters with a single big tenant.&lt;/li&gt;
&lt;li&gt;We recommend keeping it low in shared clusters because it ensures that a single tenant can&amp;rsquo;t overwhelm the read path.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;query_frontendmax_retries-parameter&#34;&gt;&lt;code&gt;query_frontend.max_retries&lt;/code&gt; parameter&lt;/h3&gt;
&lt;p&gt;This option controls the number of times to retry a request sent to a querier.
We only retry on 5xx from a queriers (&lt;em&gt;translated from the equivalent gRPC error&lt;/em&gt;).&lt;/p&gt;
&lt;h4 id=&#34;guidelines-3&#34;&gt;Guidelines&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;This option controls the retries from query-frontend to queriers.&lt;/li&gt;
&lt;li&gt;High &lt;code&gt;max_retries&lt;/code&gt; amplifies the slow queriers and result in a lot more load then required.&lt;/li&gt;
&lt;li&gt;Low &lt;code&gt;max_retries&lt;/code&gt; can lead to users having bad experience due failed queriers, because  a job failed and wasn’t retried.&lt;/li&gt;
&lt;li&gt;If there are too many retries in a cluster, it can be a sign that queriers are struggling to finish work and needs to be scaled up.&lt;/li&gt;
&lt;li&gt;Big jobs (high &lt;code&gt;target_bytes_per_job&lt;/code&gt; or &lt;code&gt;max_batch_size&lt;/code&gt;) can result in increased retries. Make the jobs smaller by reducing the &lt;code&gt;target_bytes_per_job&lt;/code&gt; or &lt;code&gt;max_batch_size&lt;/code&gt; to reduce the retries. If not, scale up the queriers.&lt;/li&gt;
&lt;li&gt;Don&amp;rsquo;t set &lt;code&gt;query_frontend.max_retries&lt;/code&gt; to a high number. The default of &lt;code&gt;2&lt;/code&gt; is a good default.&lt;/li&gt;
&lt;li&gt;Higher retries impact the backend when you have a big query that’s generating lots of jobs.&lt;/li&gt;
&lt;li&gt;High &lt;code&gt;max_retries&lt;/code&gt; can overwhelm the queriers when they&amp;rsquo;re under heavy load and failing to process the jobs. Retries can snowball, and degrade the query performance.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;query_frontendsearchtarget_bytes_per_job-parameter&#34;&gt;&lt;code&gt;query_frontend.search.target_bytes_per_job&lt;/code&gt; parameter&lt;/h3&gt;
&lt;p&gt;The target number of bytes for each job to handle when performing a backend search.&lt;/p&gt;
&lt;p&gt;This parameter controls the size of a single job, and size of a job dictates how much data a single job reads.
You can tune this to make big or small jobs.&lt;/p&gt;
&lt;p&gt;This option controls the upper limit on the size of a job, and can be used as a proxy for  how much data a single search job scans or the amount of work a querier needs to do to process a job.&lt;/p&gt;
&lt;h4 id=&#34;guidelines-4&#34;&gt;Guidelines&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;Setting this to a small value produces too many jobs, and results in more overhead, setting it too high produces big jobs. Queriers might struggle to finish those jobs and it can lead to high latency.&lt;/li&gt;
&lt;li&gt;In testing at Grafana Labs, 100MB to 200MB is a good range for this configuration, and works across different sizes of clusters.&lt;/li&gt;
&lt;li&gt;We recommend keeping this fixed within the recommended range.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;querierfrontend_workerparallelism-parameter&#34;&gt;&lt;code&gt;querier.frontend_worker.parallelism&lt;/code&gt; parameter&lt;/h3&gt;
&lt;p&gt;Number of simultaneous queries to process per query-frontend or query-scheduler. This configuration controls the number of concurrent requests per query-frontend a querier process.&lt;/p&gt;
&lt;p&gt;If parallelism is set to 5 and there are two query-frontends running, then a querier process opens 5 connections to each query-frontend, and in total of 10 connections.&lt;/p&gt;
&lt;p&gt;One batch (or job, if batching is disabled) is processed per connection, so this controls the maximum number of concurrent jobs processed.&lt;/p&gt;
&lt;p&gt;A single batch is processed in sync and size of the batch is controlled by &lt;code&gt;max_batch_size&lt;/code&gt;, a connection is blocked until it&amp;rsquo;s process and returns the result of a batch.&lt;/p&gt;
&lt;p&gt;You can also disable it and use &lt;code&gt;max_concurrent_connections&lt;/code&gt; but we use this to make sure we queriers are picking up work from both query-frontends and jobs are being scheduled fairly.&lt;/p&gt;
&lt;p&gt;If you want to make sure you always have connections defined in this config, you should set  &lt;code&gt;match_max_concurrent: false&lt;/code&gt; in your configuration to ensure you are not limited by &lt;code&gt;max_concurrent_connections&lt;/code&gt;.&lt;/p&gt;
&lt;h4 id=&#34;guidelines-5&#34;&gt;Guidelines&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;Maximum number of jobs a querier processes when using parallelism is equal to &lt;code&gt;parallelism * query_frontend replicas * max_batch_size&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;As you add more queriers, connections to an individual frontend increase. Query-frontend has a shared lock on these connections so if you see issues when you scale out queriers, lower the parallelism to reduce contention.&lt;/li&gt;
&lt;li&gt;It’s recommended to set &lt;code&gt;match_max_concurrent: false&lt;/code&gt; and not set &lt;code&gt;max_concurrent_queries&lt;/code&gt; when using parallelism.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;queriermax_concurrent_queries-parameter&#34;&gt;&lt;code&gt;querier.max_concurrent_queries&lt;/code&gt; parameter&lt;/h3&gt;
&lt;p&gt;This controls the maximum number of jobs a querier processes concurrently. It doesn&amp;rsquo;t distinguish between the types of queries. These jobs can be from two different queries, or different tenants as well.&lt;/p&gt;
&lt;p&gt;Querier processes these in sync, blocks the connection, and once it returns the results, it picks up a new job from the query-frontend queue.&lt;/p&gt;
&lt;h4 id=&#34;guidelines-6&#34;&gt;Guidelines&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;The &lt;code&gt;max_concurrent_queries&lt;/code&gt; parameter controls the number of queries that are processed by querier at once (concurrently).&lt;/li&gt;
&lt;li&gt;if queriers are under-utilized, increase this value to process more jobs concurrently and process the queries faster.&lt;/li&gt;
&lt;li&gt;If queriers are over utilized, seeing spikes, or OOMs, you can reduce this config to do less work per queriers and scale out queriers to add more capacity to the cluster.&lt;/li&gt;
&lt;li&gt;This setting depends on the resources, in small queriers, it should be set to a lower number.&lt;/li&gt;
&lt;li&gt;If you have large queriers, this configuration should be set to a higher value to fully utilize the capacity of the querier.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;querier-memory-sizing&#34;&gt;Querier memory sizing&lt;/h2&gt;
&lt;p&gt;If you are seeing that your queries are using more memory then you prefer, reduce the amount of work a querier is doing concurrently. That reduces resource usage.&lt;/p&gt;
&lt;p&gt;If you want your queries to use more memory then they&amp;rsquo;re currently using, increase the amount of work a querier is doing concurrently and it increases the resource usage.&lt;/p&gt;
&lt;p&gt;You can tune &lt;code&gt;query_frontend.search.target_bytes_per_job&lt;/code&gt;, &lt;code&gt;querier.frontend_worker.parallelism&lt;/code&gt;, and &lt;code&gt;querier.max_concurrent_queries&lt;/code&gt; to tune the amount of work a querier is doing concurrently.&lt;/p&gt;
&lt;p&gt;Queriers memory request roughly translates to job size times the concurrent work and some buffer.&lt;/p&gt;
&lt;h2 id=&#34;scaling-cache&#34;&gt;Scaling cache&lt;/h2&gt;
&lt;p&gt;Tempo can be configured to use multiple caches for different types of data.
When configured, Tempo uses these caches to improve the performance of queries.&lt;/p&gt;
&lt;p&gt;Here are few general heuristics to know when to scale a cache:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Look at cache latency. If cache latency is hitting &lt;code&gt;cache_timeout&lt;/code&gt;, that means that cache is under scaled and it’s taking too long to read or write, scale the cache.&lt;/li&gt;
&lt;li&gt;Scale the cache if a cache has a high eviction rate. The cache might be under provisioned.&lt;/li&gt;
&lt;li&gt;Lower level cache like bloom cache, parquet-page cache, parquet-footer cache sees higher hit rates (usually around 90% of above). If you have a consistent query traffic and these lower level caches have low hit rate, they&amp;rsquo;re undervalued and needs to be scaled up.&lt;/li&gt;
&lt;li&gt;Higher level cache like frontend-search cache has a low hit rate and is only useful when the same query is being repeated. Size these according to the amount of data you want you want to cache&lt;/li&gt;
&lt;li&gt;Cache sizes are also dictated by how much data you want to cache at each tier, it’s better to cache more at lower level caches because they have higher hit rate and is useful across queries.&lt;/li&gt;
&lt;/ul&gt;
]]></content><description>&lt;h1 id="tune-search-performance">Tune search performance&lt;/h1>
&lt;p>Regardless of whether or not you are using TraceQL or the original search API, Tempo searches all of the blocks
in the specified time range.
Depending on your volume, this may result in slow queries.&lt;/p></description></item><item><title>Improve performance with caching</title><link>https://grafana.com/docs/tempo/v2.10.x/operations/caching/</link><pubDate>Thu, 09 Apr 2026 14:59:14 +0000</pubDate><guid>https://grafana.com/docs/tempo/v2.10.x/operations/caching/</guid><content><![CDATA[&lt;h1 id=&#34;improve-performance-with-caching&#34;&gt;Improve performance with caching&lt;/h1&gt;
&lt;p&gt;Caching is mainly used to improve query performance by storing bloom filters of all backend blocks which are accessed on every query.&lt;/p&gt;
&lt;p&gt;Tempo uses an external cache to improve query performance.
Tempo supports &lt;a href=&#34;https://memcached.org/&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;Memcached&lt;/a&gt; and &lt;a href=&#34;https://redis.io/&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;Redis&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;For information about search performance, refer to &lt;a href=&#34;/docs/tempo/latest/operations/backend_search/&#34;&gt;Tune search performance&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&#34;memcached&#34;&gt;Memcached&lt;/h2&gt;
&lt;p&gt;Memcached is one of the cache implementations supported by Tempo.
It&amp;rsquo;s used by default in the Tanka and Helm examples.
Refer to &lt;a href=&#34;../../set-up-for-tracing/setup-tempo/deploy/&#34;&gt;Deploying Tempo&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&#34;connection-limit&#34;&gt;Connection limit&lt;/h3&gt;
&lt;p&gt;As a cluster grows in size, the number of instances of Tempo connecting to the cache servers also increases.
By default, Memcached has a connection limit of 1024.
Memcached refuses connections when this limit is surpassed.
You can resolve this issue by increasing the connection limit of Memcached.&lt;/p&gt;
&lt;p&gt;You can use the &lt;code&gt;tempo_memcache_request_duration_seconds_count&lt;/code&gt; metric to observe these errors.
For example, by using the following query:&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;promql&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-promql&#34;&gt;sum by (status_code) (
  rate(tempo_memcache_request_duration_seconds_count{}[$__rate_interval])
)&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;This metric is also shown in &lt;a href=&#34;../monitor/&#34;&gt;the monitoring dashboards&lt;/a&gt; (the left panel):&lt;/p&gt;
&lt;p&gt;&lt;img
  class=&#34;lazyload d-inline-block&#34;
  data-src=&#34;/media/docs/tempo/caching_memcached_connection_limit.png&#34;
  alt=&#34;QPS and latency of requests to memcached&#34; width=&#34;1631&#34;
     height=&#34;274&#34;/&gt;&lt;/p&gt;
&lt;p&gt;Note that the already open connections continue to function. New connections are refused.&lt;/p&gt;
&lt;p&gt;Additionally, Memcached logs the following errors when it can&amp;rsquo;t accept any new requests:&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;accept4(): No file descriptors available
Too many open connections
accept4(): No file descriptors available
Too many open connections&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;When using the &lt;a href=&#34;https://github.com/prometheus/memcached_exporter&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;memcached_exporter&lt;/a&gt;, you can observe the number of open connections at &lt;code&gt;memcached_current_connections&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id=&#34;cache-size-control&#34;&gt;Cache size control&lt;/h2&gt;
&lt;p&gt;Tempo querier accesses bloom filters of all blocks while searching for a trace.
This essentially mandates the size of cache to be at-least the total size of the bloom filters (the working set).
However, in larger deployments, the working set might be larger than the desired size of cache.
When that happens, eviction rates on the cache grow high, and hit rate drop.&lt;/p&gt;
&lt;p&gt;Tempo provides two configuration parameters to filter down on the items stored in cache.&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;        # Min compaction level of block to qualify for caching bloom filter
        # Example: &amp;#34;cache_min_compaction_level: 2&amp;#34;
        [cache_min_compaction_level: &amp;lt;int&amp;gt;]

        # Max block age to qualify for caching bloom filter
        # Example: &amp;#34;cache_max_block_age: 48h&amp;#34;
        [cache_max_block_age: &amp;lt;duration&amp;gt;]&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Using a combination of these configuration options, you can narrow down on which bloom filters are cached, thereby reducing the
cache eviction rate, and increasing the cache hit rate.&lt;/p&gt;
&lt;p&gt;In order to decide the values of these configuration parameters, you can use a cache summary command in the &lt;a href=&#34;../tempo_cli/&#34;&gt;tempo-cli&lt;/a&gt; that
prints a summary of bloom filter shards per day and per compaction level. The result looks something like this:&lt;/p&gt;
&lt;p&gt;&lt;img
  class=&#34;lazyload d-inline-block&#34;
  data-src=&#34;/media/docs/tempo/cache-summary.png&#34;
  alt=&#34;Cache summary output&#34; width=&#34;2176&#34;
     height=&#34;418&#34;/&gt;&lt;/p&gt;
&lt;p&gt;This image shows the bloom filter shards over 14 days and 6 compaction levels. This can be used to decide the configuration parameters.&lt;/p&gt;
]]></content><description>&lt;h1 id="improve-performance-with-caching">Improve performance with caching&lt;/h1>
&lt;p>Caching is mainly used to improve query performance by storing bloom filters of all backend blocks which are accessed on every query.&lt;/p></description></item><item><title>Manage advanced systems</title><link>https://grafana.com/docs/tempo/v2.10.x/operations/manage-advanced-systems/</link><pubDate>Thu, 09 Apr 2026 14:59:14 +0000</pubDate><guid>https://grafana.com/docs/tempo/v2.10.x/operations/manage-advanced-systems/</guid><content><![CDATA[&lt;h1 id=&#34;manage-advanced-systems&#34;&gt;Manage advanced systems&lt;/h1&gt;
&lt;p&gt;This section provides resources for managing and tuning advanced Tempo configurations.&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;
    &lt;a href=&#34;/docs/tempo/v2.10.x/operations/manage-advanced-systems/multitenancy/&#34;&gt;Enable multi-tenancy&lt;/a&gt;&lt;/li&gt;&lt;li&gt;
    &lt;a href=&#34;/docs/tempo/v2.10.x/operations/manage-advanced-systems/cross_tenant_query/&#34;&gt;Cross-tenant query federation&lt;/a&gt;&lt;/li&gt;&lt;li&gt;
    &lt;a href=&#34;/docs/tempo/v2.10.x/operations/manage-advanced-systems/user-configurable-overrides/&#34;&gt;User-configurable overrides&lt;/a&gt;&lt;/li&gt;&lt;li&gt;
    &lt;a href=&#34;/docs/tempo/v2.10.x/operations/manage-advanced-systems/generic_forwarding/&#34;&gt;Generic forwarding&lt;/a&gt;&lt;/li&gt;&lt;li&gt;
    &lt;a href=&#34;/docs/tempo/v2.10.x/operations/manage-advanced-systems/consistent_hash_ring/&#34;&gt;Tune the consistent hash rings&lt;/a&gt;&lt;/li&gt;&lt;li&gt;
    &lt;a href=&#34;/docs/tempo/v2.10.x/operations/manage-advanced-systems/zone-aware-ingesters/&#34;&gt;Zone-aware replication for ingesters&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;
]]></content><description>&lt;h1 id="manage-advanced-systems">Manage advanced systems&lt;/h1>
&lt;p>This section provides resources for managing and tuning advanced Tempo configurations.&lt;/p>
&lt;ul>&lt;li>
&lt;a href="/docs/tempo/v2.10.x/operations/manage-advanced-systems/multitenancy/">Enable multi-tenancy&lt;/a>&lt;/li>&lt;li>
&lt;a href="/docs/tempo/v2.10.x/operations/manage-advanced-systems/cross_tenant_query/">Cross-tenant query federation&lt;/a>&lt;/li>&lt;li>
&lt;a href="/docs/tempo/v2.10.x/operations/manage-advanced-systems/user-configurable-overrides/">User-configurable overrides&lt;/a>&lt;/li>&lt;li>
&lt;a href="/docs/tempo/v2.10.x/operations/manage-advanced-systems/generic_forwarding/">Generic forwarding&lt;/a>&lt;/li>&lt;li>
&lt;a href="/docs/tempo/v2.10.x/operations/manage-advanced-systems/consistent_hash_ring/">Tune the consistent hash rings&lt;/a>&lt;/li>&lt;li>
&lt;a href="/docs/tempo/v2.10.x/operations/manage-advanced-systems/zone-aware-ingesters/">Zone-aware replication for ingesters&lt;/a>&lt;/li>&lt;/ul></description></item><item><title>Tempo CLI</title><link>https://grafana.com/docs/tempo/v2.10.x/operations/tempo_cli/</link><pubDate>Thu, 09 Apr 2026 14:59:14 +0000</pubDate><guid>https://grafana.com/docs/tempo/v2.10.x/operations/tempo_cli/</guid><content><![CDATA[&lt;h1 id=&#34;tempo-cli&#34;&gt;Tempo CLI&lt;/h1&gt;
&lt;p&gt;Tempo CLI is a separate executable that contains utility functions related to the Tempo software.
Although it&amp;rsquo;s not required for a working installation, Tempo CLI can be helpful for deeper analysis or for troubleshooting.&lt;/p&gt;
&lt;h2 id=&#34;tempo-cli-command-syntax&#34;&gt;Tempo CLI command syntax&lt;/h2&gt;
&lt;p&gt;The general syntax for commands in Tempo CLI is:&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;Bash&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-bash&#34;&gt;tempo-cli command [subcommand] [options] [arguments...]&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;&lt;code&gt;--help&lt;/code&gt; or &lt;code&gt;-h&lt;/code&gt; displays the help for a command or subcommand.&lt;/p&gt;
&lt;p&gt;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;Bash&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-bash&#34;&gt;tempo-cli -h
tempo-cli command [subcommand] -h&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;h2 id=&#34;run-tempo-cli&#34;&gt;Run Tempo CLI&lt;/h2&gt;
&lt;p&gt;Tempo CLI is currently available as source code.&lt;/p&gt;
&lt;p&gt;To build Tempo CLI, you need a working Go installation and a build environment.
You can compile it to a native binary and execute normally, or you can execute it using the &lt;code&gt;go run&lt;/code&gt; command.
You can also package it as a binary in a Docker container using &lt;code&gt;make docker-tempo-cli&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;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;Bash&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-bash&#34;&gt;./tempo-cli [arguments...]
go run ./cmd/tempo-cli [arguments...]&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;Bash&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-bash&#34;&gt;make docker-tempo-cli
docker run docker.io/grafana/tempo-cli [arguments...]&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;h2 id=&#34;backend-options&#34;&gt;Backend options&lt;/h2&gt;
&lt;p&gt;Tempo CLI connects directly to the storage backend for some commands, meaning that it requires the ability to read from S3, GCS, Azure or file-system storage.
You can configure the backend using the following options:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Load an existing tempo configuration file using the &lt;code&gt;--config-file&lt;/code&gt; (&lt;code&gt;-c&lt;/code&gt;) option. This is the recommended option
for frequent usage. Refer to &lt;a href=&#34;../../configuration/&#34;&gt;Configuration&lt;/a&gt; documentation for more information.&lt;/li&gt;
&lt;li&gt;Specify individual settings:
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;--backend &amp;lt;value&amp;gt;&lt;/code&gt; The storage backend type, one of &lt;code&gt;s3&lt;/code&gt;, &lt;code&gt;gcs&lt;/code&gt;, &lt;code&gt;azure&lt;/code&gt;, and &lt;code&gt;local&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;--bucket &amp;lt;value&amp;gt;&lt;/code&gt; The bucket name. The meaning of this value is backend-specific. Refer to &lt;a href=&#34;../../configuration/&#34;&gt;Configuration&lt;/a&gt; documentation for more information.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;--s3-endpoint &amp;lt;value&amp;gt;&lt;/code&gt; The S3 API endpoint (i.e. s3.dualstack.us-east-2.amazonaws.com).&lt;/li&gt;
&lt;li&gt;&lt;code&gt;--s3-user &amp;lt;value&amp;gt;&lt;/code&gt;, &lt;code&gt;--s3-pass &amp;lt;value&amp;gt;&lt;/code&gt; The S3 user name and password (or access key and secret key).
Optional, as Tempo CLI supports the same authentication mechanisms as Tempo. Refer to &lt;a href=&#34;../../configuration/hosted-storage/s3/&#34;&gt;S3 permissions documentation&lt;/a&gt; for more information.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;--insecure-skip-verify&lt;/code&gt; skip TLS verification, only applies to S3 and GCS.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Each option applies only to the command in which it&amp;rsquo;s used. For example, &lt;code&gt;--backend &amp;lt;value&amp;gt;&lt;/code&gt; doesn&amp;rsquo;t permanently change where Tempo stores data. It only changes it for command in which you apply the option.&lt;/p&gt;
&lt;h2 id=&#34;query-api-command&#34;&gt;Query API command&lt;/h2&gt;
&lt;h3 id=&#34;trace-id&#34;&gt;Trace ID&lt;/h3&gt;
&lt;p&gt;Call the Tempo API and retrieve a trace by ID.&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;Bash&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-bash&#34;&gt;tempo-cli query api trace-id &amp;lt;api-endpoint&amp;gt; &amp;lt;trace-id&amp;gt;&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Arguments:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;api-endpoint&lt;/code&gt; URL for the Tempo API.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;trace-id&lt;/code&gt; Trace ID as a hexadecimal string.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Options:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;--org-id &amp;lt;value&amp;gt;&lt;/code&gt; Organization ID (for use in multi-tenant setup).&lt;/li&gt;
&lt;li&gt;&lt;code&gt;--v1&lt;/code&gt; use v1 API (use /api/traces endpoint to fetch traces, default: /api/v2/traces).&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;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;Bash&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-bash&#34;&gt;tempo-cli query api trace-id http://tempo:3200 f1cfe82a8eef933b&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;h3 id=&#34;search&#34;&gt;Search&lt;/h3&gt;
&lt;p&gt;Call the Tempo API and search using TraceQL.&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;Bash&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-bash&#34;&gt;tempo-cli query api search &amp;lt;host-port&amp;gt; &amp;lt;trace-ql&amp;gt; [&amp;lt;start&amp;gt; &amp;lt;end&amp;gt;]&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Arguments:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;host-port&lt;/code&gt; A host/port combination for Tempo. The scheme is inferred from the options.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;trace-ql&lt;/code&gt; TraceQL query.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;start&lt;/code&gt; Start of the time range to search: (YYYY-MM-DDThh:mm:ss)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;end&lt;/code&gt; End of the time range to search: (YYYY-MM-DDThh:mm:ss)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Options:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;--org-id &amp;lt;value&amp;gt;&lt;/code&gt; Organization ID (for use in multi-tenant setup).&lt;/li&gt;
&lt;li&gt;&lt;code&gt;--use-grpc&lt;/code&gt; Use GRPC streaming&lt;/li&gt;
&lt;li&gt;&lt;code&gt;--spss &amp;lt;value&amp;gt;&lt;/code&gt; Number of spans to return for each spanset&lt;/li&gt;
&lt;li&gt;&lt;code&gt;--limit &amp;lt;value&amp;gt;&lt;/code&gt; Number of results to return&lt;/li&gt;
&lt;li&gt;&lt;code&gt;--path-prefix &amp;lt;value&amp;gt;&lt;/code&gt; String to prefix search paths with&lt;/li&gt;
&lt;li&gt;&lt;code&gt;--secure&lt;/code&gt; Use HTTPS or gRPC with TLS&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;Set the &lt;code&gt;stream_over_http_enabled&lt;/code&gt; flag to true in the Tempo configuration to enable streaming over HTTP. For more information, refer to &lt;a href=&#34;../../api_docs/&#34;&gt;Tempo GRPC API documentation&lt;/a&gt;.&lt;/p&gt;&lt;/blockquote&gt;&lt;/div&gt;

&lt;h3 id=&#34;search-tags&#34;&gt;Search tags&lt;/h3&gt;
&lt;p&gt;Call the Tempo API and search attribute names.&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;Bash&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-bash&#34;&gt;tempo-cli query api search-tags &amp;lt;host-port&amp;gt; [&amp;lt;start&amp;gt; &amp;lt;end&amp;gt;]&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Arguments:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;host-port&lt;/code&gt; A host/port combination for Tempo. The scheme will be inferred based on the options provided.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;start&lt;/code&gt; Start of the time range to search: (YYYY-MM-DDThh:mm:ss)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;end&lt;/code&gt; End of the time range to search: (YYYY-MM-DDThh:mm:ss)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Options:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;--org-id &amp;lt;value&amp;gt;&lt;/code&gt; Organization ID (for use in multi-tenant setup).&lt;/li&gt;
&lt;li&gt;&lt;code&gt;--use-grpc&lt;/code&gt; Use GRPC streaming&lt;/li&gt;
&lt;li&gt;&lt;code&gt;--path-prefix &amp;lt;value&amp;gt;&lt;/code&gt; String to prefix search paths with&lt;/li&gt;
&lt;li&gt;&lt;code&gt;--secure&lt;/code&gt; Use HTTPS or gRPC with TLS&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;Set the &lt;code&gt;stream_over_http_enabled&lt;/code&gt; flag to true in the Tempo configuration to enable streaming over HTTP. For more information, refer to &lt;a href=&#34;../../api_docs/&#34;&gt;Tempo GRPC API documentation&lt;/a&gt;.&lt;/p&gt;&lt;/blockquote&gt;&lt;/div&gt;

&lt;h3 id=&#34;search-tag-values&#34;&gt;Search tag values&lt;/h3&gt;
&lt;p&gt;Call the Tempo API and search attribute values.&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;Bash&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-bash&#34;&gt;tempo-cli query api search-tag-values &amp;lt;host-port&amp;gt; &amp;lt;tag&amp;gt; [&amp;lt;start&amp;gt; &amp;lt;end&amp;gt;]&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Arguments:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;host-port&lt;/code&gt; A host/port combination for Tempo. The scheme is inferred from the options.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;tag&lt;/code&gt; The fully qualified TraceQL tag to search for. For example, &lt;code&gt;resource.service.name&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;start&lt;/code&gt; Start of the time range to search: (YYYY-MM-DDThh:mm:ss)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;end&lt;/code&gt; End of the time range to search: (YYYY-MM-DDThh:mm:ss)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Options:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;--org-id &amp;lt;value&amp;gt;&lt;/code&gt; Organization ID (for use in multi-tenant setup).&lt;/li&gt;
&lt;li&gt;&lt;code&gt;--use-grpc&lt;/code&gt; Use GRPC streaming&lt;/li&gt;
&lt;li&gt;&lt;code&gt;--path-prefix &amp;lt;value&amp;gt;&lt;/code&gt; String to prefix search paths with&lt;/li&gt;
&lt;li&gt;&lt;code&gt;--secure&lt;/code&gt; Use HTTP or gRPC with TLS&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;Set the &lt;code&gt;stream_over_http_enabled&lt;/code&gt; flag to true in the Tempo configuration to enable streaming over HTTP. For more information, refer to &lt;a href=&#34;../../api_docs/&#34;&gt;Tempo GRPC API documentation&lt;/a&gt;.&lt;/p&gt;&lt;/blockquote&gt;&lt;/div&gt;

&lt;h3 id=&#34;metrics&#34;&gt;Metrics&lt;/h3&gt;
&lt;p&gt;Call the Tempo API and generate metrics from traces using TraceQL.&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;Bash&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-bash&#34;&gt;tempo-cli query api metrics &amp;lt;host-port&amp;gt; &amp;lt;trace-ql metrics query&amp;gt; [&amp;lt;start&amp;gt; &amp;lt;end&amp;gt;]&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Arguments:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;host-port&lt;/code&gt; A host/port combination for Tempo. The scheme will be inferred based on the options provided.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;trace-ql metrics query&lt;/code&gt; TraceQL metrics query.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;start&lt;/code&gt; Start of the time range to search: (YYYY-MM-DDThh:mm:ss)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;end&lt;/code&gt; End of the time range to search: (YYYY-MM-DDThh:mm:ss)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Options:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;--org-id &amp;lt;value&amp;gt;&lt;/code&gt; Organization ID (for use in multi-tenant setup).&lt;/li&gt;
&lt;li&gt;&lt;code&gt;--use-grpc&lt;/code&gt; Use GRPC streaming&lt;/li&gt;
&lt;li&gt;&lt;code&gt;--path-prefix &amp;lt;value&amp;gt;&lt;/code&gt; String to prefix search paths with&lt;/li&gt;
&lt;li&gt;&lt;code&gt;--secure&lt;/code&gt; Use HTTPS or gRPC with TLS&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;Set the &lt;code&gt;stream_over_http_enabled&lt;/code&gt; flag to true in the Tempo configuration to enable streaming over HTTP. For more information, refer to &lt;a href=&#34;../../api_docs/&#34;&gt;Tempo GRPC API documentation&lt;/a&gt;.&lt;/p&gt;&lt;/blockquote&gt;&lt;/div&gt;

&lt;h2 id=&#34;query-blocks-command&#34;&gt;Query blocks command&lt;/h2&gt;
&lt;p&gt;Iterate over all backend blocks and dump all data found for a given trace id.&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;Bash&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-bash&#34;&gt;tempo-cli query blocks &amp;lt;trace-id&amp;gt; &amp;lt;tenant-id&amp;gt;&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&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;This can be intense as it downloads every bloom filter and some percentage of indexes/trace data.&lt;/p&gt;&lt;/blockquote&gt;&lt;/div&gt;

&lt;p&gt;Arguments:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;trace-id&lt;/code&gt; Trace ID as a hexadecimal string.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;tenant-id&lt;/code&gt; Tenant to search.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Options:
See backend options above.&lt;/p&gt;
&lt;p&gt;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;Bash&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-bash&#34;&gt;tempo-cli query blocks f1cfe82a8eef933b single-tenant&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;h2 id=&#34;query-trace-summary-command&#34;&gt;Query trace summary command&lt;/h2&gt;
&lt;p&gt;Iterate over all backend blocks and dump a summary for a given trace id.&lt;/p&gt;
&lt;p&gt;The summary includes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;number of blocks the trace is found in&lt;/li&gt;
&lt;li&gt;span count&lt;/li&gt;
&lt;li&gt;trace size&lt;/li&gt;
&lt;li&gt;trace duration&lt;/li&gt;
&lt;li&gt;root service name&lt;/li&gt;
&lt;li&gt;root span info&lt;/li&gt;
&lt;li&gt;top frequent service names&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;Bash&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-bash&#34;&gt;tempo-cli query trace-summary &amp;lt;trace-id&amp;gt; &amp;lt;tenant-id&amp;gt;&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; can be intense as it downloads every bloom filter and some percentage of indexes/trace data.&lt;/p&gt;
&lt;p&gt;Arguments:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;trace-id&lt;/code&gt; Trace ID as a hexadecimal string.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;tenant-id&lt;/code&gt; Tenant to search.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Options:
See backend options above.&lt;/p&gt;
&lt;p&gt;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;Bash&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-bash&#34;&gt;tempo-cli query trace-summary f1cfe82a8eef933b single-tenant&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;h2 id=&#34;list-blocks&#34;&gt;List blocks&lt;/h2&gt;
&lt;p&gt;Lists information about all blocks for the given tenant, and optionally perform integrity checks on indexes for duplicate records.&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;Bash&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-bash&#34;&gt;tempo-cli list blocks &amp;lt;tenant-id&amp;gt;&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Arguments:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;tenant-id&lt;/code&gt; The tenant ID. Use &lt;code&gt;single-tenant&lt;/code&gt; for single tenant setups.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Options:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;--include-compacted&lt;/code&gt; Include blocks that have been compacted. Default behavior is to display only active blocks.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Output:&lt;/strong&gt;
Explanation of output:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;ID&lt;/code&gt; Block ID.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Lvl&lt;/code&gt; Compaction level of the block.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Objects&lt;/code&gt; Number of objects stored in the block.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Size&lt;/code&gt; Data size of the block after any compression.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Encoding&lt;/code&gt; Block encoding (compression algorithm).&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Vers&lt;/code&gt; Block version.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Window&lt;/code&gt; The window of time that was considered for compaction purposes.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Start&lt;/code&gt; The earliest timestamp stored in the block.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;End&lt;/code&gt; The latest timestamp stored in the block.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Duration&lt;/code&gt;Duration between the start and end time.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Age&lt;/code&gt; The age of the block.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Cmp&lt;/code&gt; Whether the block has been compacted (present when &amp;ndash;include-compacted is specified).&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;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;Bash&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-bash&#34;&gt;tempo-cli list blocks -c ./tempo.yaml single-tenant&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;h2 id=&#34;list-block&#34;&gt;List block&lt;/h2&gt;
&lt;p&gt;Lists information about a single block, and optionally, scan its contents.&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;Bash&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-bash&#34;&gt;tempo-cli list block &amp;lt;tenant-id&amp;gt; &amp;lt;block-id&amp;gt;&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Arguments:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;tenant-id&lt;/code&gt; The tenant ID. Use &lt;code&gt;single-tenant&lt;/code&gt; for single tenant setups.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;block-id&lt;/code&gt; The block ID as UUID string.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Options:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;--scan&lt;/code&gt; Also load the block data, perform integrity check for duplicates, and collect statistics. &lt;strong&gt;Note:&lt;/strong&gt; can be intense.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;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;Bash&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-bash&#34;&gt;tempo-cli list block -c ./tempo.yaml single-tenant ca314fba-efec-4852-ba3f-8d2b0bbf69f1&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;h2 id=&#34;list-compaction-summary&#34;&gt;List compaction summary&lt;/h2&gt;
&lt;p&gt;Summarizes information about all blocks for the given tenant based on compaction level. This command is useful to analyze or troubleshoot compactor behavior.&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;Bash&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-bash&#34;&gt;tempo-cli list compaction-summary &amp;lt;tenant-id&amp;gt;&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Arguments:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;tenant-id&lt;/code&gt; The tenant ID. Use &lt;code&gt;single-tenant&lt;/code&gt; for single tenant setups.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;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;Bash&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-bash&#34;&gt;tempo-cli list compaction-summary -c ./tempo.yaml single-tenant&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;h2 id=&#34;list-cache-summary&#34;&gt;List cache summary&lt;/h2&gt;
&lt;p&gt;Prints information about the number of bloom filter shards per day per compaction level. This command is useful to
estimate and fine-tune cache storage. Read the &lt;a href=&#34;../caching/&#34;&gt;caching topic&lt;/a&gt; for more information.&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;Bash&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-bash&#34;&gt;tempo-cli list cache-summary &amp;lt;tenant-id&amp;gt;&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Arguments:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;tenant-id&lt;/code&gt; The tenant ID. Use &lt;code&gt;single-tenant&lt;/code&gt; for single tenant setups.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;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;Bash&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-bash&#34;&gt;tempo-cli list cache-summary -c ./tempo.yaml single-tenant&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;h2 id=&#34;list-index&#34;&gt;List index&lt;/h2&gt;
&lt;p&gt;Lists basic index info for the given block.&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;Bash&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-bash&#34;&gt;tempo-cli list index &amp;lt;tenant-id&amp;gt; &amp;lt;block-id&amp;gt;&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Arguments:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;tenant-id&lt;/code&gt; The tenant ID. Use &lt;code&gt;single-tenant&lt;/code&gt; for single tenant setups.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;block-id&lt;/code&gt; The block ID as UUID string.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;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;Bash&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-bash&#34;&gt;tempo-cli list index -c ./tempo.yaml single-tenant ca314fba-efec-4852-ba3f-8d2b0bbf69f1&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;h2 id=&#34;view-index&#34;&gt;View index&lt;/h2&gt;
&lt;p&gt;View the index contents for the given block.&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;Bash&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-bash&#34;&gt;tempo-cli view index &amp;lt;tenant-id&amp;gt; &amp;lt;block-id&amp;gt;&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Arguments:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;tenant-id&lt;/code&gt; The tenant ID. Use &lt;code&gt;single-tenant&lt;/code&gt; for single tenant setups.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;block-id&lt;/code&gt; The block ID as UUID string.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;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;Bash&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-bash&#34;&gt;tempo-cli view index -c ./tempo.yaml single-tenant ca314fba-efec-4852-ba3f-8d2b0bbf69f1&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;h2 id=&#34;generate-bloom-filter&#34;&gt;Generate bloom filter&lt;/h2&gt;
&lt;p&gt;To generate the bloom filter for a block if the files were deleted/corrupted.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; ensure that the block is in a local backend in the expected directory hierarchy, i.e. &lt;code&gt;path / tenant / blocks&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Arguments:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;tenant-id&lt;/code&gt; The tenant ID. Use &lt;code&gt;single-tenant&lt;/code&gt; for single tenant setups.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;block-id&lt;/code&gt; The block ID as UUID string.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;bloom-fp&lt;/code&gt; The false positive to be used for the bloom filter.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;bloom-shard-size&lt;/code&gt; The shard size to be used for the bloom filter.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;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;Bash&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-bash&#34;&gt;tempo-cli gen bloom --backend=local --bucket=./cmd/tempo-cli/test-data/ single-tenant b18beca6-4d7f-4464-9f72-f343e688a4a0 0.05 100000&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;The bloom filter will be generated at the required location under the block folder.&lt;/p&gt;
&lt;h2 id=&#34;generate-index&#34;&gt;Generate index&lt;/h2&gt;
&lt;p&gt;To generate the index/bloom for a block if the files were deleted/corrupted.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; ensure that the block is in a local backend in the expected directory hierarchy, i.e. &lt;code&gt;path / tenant / blocks&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Arguments:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;tenant-id&lt;/code&gt; The tenant ID. Use &lt;code&gt;single-tenant&lt;/code&gt; for single tenant setups.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;block-id&lt;/code&gt; The block ID as UUID string.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;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;Bash&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-bash&#34;&gt;tempo-cli gen index --backend=local --bucket=./cmd/tempo-cli/test-data/ single-tenant b18beca6-4d7f-4464-9f72-f343e688a4a0&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;The index will be generated at the required location under the block folder.&lt;/p&gt;
&lt;h2 id=&#34;search-blocks-command&#34;&gt;Search blocks command&lt;/h2&gt;
&lt;p&gt;Search blocks in a given time range for a specific key/value pair.&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;Bash&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-bash&#34;&gt;tempo-cli search blocks &amp;lt;name&amp;gt; &amp;lt;value&amp;gt; &amp;lt;start&amp;gt; &amp;lt;end&amp;gt; &amp;lt;tenant-id&amp;gt;&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; can be intense as it downloads all relevant blocks and iterates through them.&lt;/p&gt;
&lt;p&gt;Arguments:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;name&lt;/code&gt; Name of the attribute to search for e.g. &lt;code&gt;http.post&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;value&lt;/code&gt; Value of the attribute to search for e.g. &lt;code&gt;GET&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;start&lt;/code&gt; Start of the time range to search: (YYYY-MM-DDThh:mm:ss)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;end&lt;/code&gt; End of the time range to search: (YYYY-MM-DDThh:mm:ss)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;tenant-id&lt;/code&gt; Tenant to search.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Options:
See backend options above.&lt;/p&gt;
&lt;p&gt;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;Bash&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-bash&#34;&gt;tempo-cli search blocks http.post GET 2021-09-21T00:00:00 2021-09-21T00:05:00 single-tenant --backend=gcs --bucket=tempo-trace-data&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;h2 id=&#34;parquet-convert-command&#34;&gt;Parquet convert command&lt;/h2&gt;
&lt;p&gt;Converts a parquet file from its existing schema to the one currently in the repository. This utility command is useful when
attempting to determine the impact of changing compression or encoding of columns.&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;Bash&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-bash&#34;&gt;tempo-cli parquet convert &amp;lt;in file&amp;gt; &amp;lt;out file&amp;gt;&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Arguments:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;in file&lt;/code&gt; Filename of an existing parquet file containing Tempo trace data&lt;/li&gt;
&lt;li&gt;&lt;code&gt;out file&lt;/code&gt; File to write to. (Existing file is overwritten.)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;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;Bash&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-bash&#34;&gt;tempo-cli parquet convert data.parquet out.parquet&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;h2 id=&#34;parquet-convert-a-to-b-command&#34;&gt;Parquet convert A to B command&lt;/h2&gt;
&lt;p&gt;Converts a vParquet file (actual data.parquet) of format A to a block of newer format B with an optional list of dedicated attribute columns.
Actual supported versions for A and B vary by Tempo release. This utility command is useful when testing the impact of different combinations
of dedicated columns.&lt;/p&gt;
&lt;h3 id=&#34;convert-vparquet3-to-vparquet4&#34;&gt;Convert vParquet3 to vParquet4&lt;/h3&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;Bash&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-bash&#34;&gt;tempo-cli parquet convert-3-to-4 &amp;lt;in file&amp;gt; [&amp;lt;out path&amp;gt;] [&amp;lt;list of dedicated columns&amp;gt;]&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Arguments:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;in file&lt;/code&gt; Path to an existing vParquet3 block directory.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;out path&lt;/code&gt; Path to write the vParquet4 block to. The default is &lt;code&gt;./out&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;list of dedicated columns&lt;/code&gt; Optional list of columns to make dedicated. Columns use TraceQL syntax with scope. For example, &lt;code&gt;span.db.statement&lt;/code&gt;, &lt;code&gt;resource.namespace&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;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;Bash&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-bash&#34;&gt;tempo-cli parquet convert-3-to-4 data.parquet ./out span.db.statement span.db.name&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;h3 id=&#34;convert-vparquet4-to-vparquet5&#34;&gt;Convert vParquet4 to vParquet5&lt;/h3&gt;
&lt;p&gt;Converts a vParquet4 block to vParquet5 format with an optional list of dedicated attribute columns.&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;Bash&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-bash&#34;&gt;tempo-cli parquet convert-4-to-5 &amp;lt;in file&amp;gt; [&amp;lt;out path&amp;gt;] [&amp;lt;list of dedicated columns&amp;gt;]&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Arguments:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;in file&lt;/code&gt; Path to an existing vParquet4 block directory.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;out path&lt;/code&gt; Path to write the vParquet5 block to. The default is &lt;code&gt;./out&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;list of dedicated columns&lt;/code&gt; Optional list of columns to make dedicated. Columns use TraceQL syntax with scope. For example, &lt;code&gt;span.http.method&lt;/code&gt;, &lt;code&gt;resource.namespace&lt;/code&gt;, &lt;code&gt;event.exception.message&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Column prefixes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;int/&lt;/code&gt; marks the column as an integer type. For example, &lt;code&gt;int/span.http.status_code&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;blob/&lt;/code&gt; marks the column for blob encoding. For example, &lt;code&gt;blob/span.db.statement&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;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;Bash&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-bash&#34;&gt;tempo-cli parquet convert-4-to-5 ./block-in ./block-out &amp;#34;span.http.method&amp;#34; &amp;#34;int/span.http.status_code&amp;#34; &amp;#34;blob/span.db.statement&amp;#34;&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;h2 id=&#34;migrate-tenant-command&#34;&gt;Migrate tenant command&lt;/h2&gt;
&lt;p&gt;Copy blocks from one backend and tenant to another. Blocks can be copied within the same backend or between two
different backends. The data format isn&amp;rsquo;t converted but the tenant ID in &lt;code&gt;meta.json&lt;/code&gt; is rewritten.&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;Bash&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-bash&#34;&gt;tempo-cli migrate tenant &amp;lt;source tenant&amp;gt; &amp;lt;dest tenant&amp;gt;&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Arguments:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;source tenant&lt;/code&gt; Tenant to copy blocks from&lt;/li&gt;
&lt;li&gt;&lt;code&gt;dest tenant&lt;/code&gt; Tenant to copy blocks into&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Options:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;--source-config-file &amp;lt;value&amp;gt;&lt;/code&gt; Configuration file for the source backend&lt;/li&gt;
&lt;li&gt;&lt;code&gt;--config-file &amp;lt;value&amp;gt;&lt;/code&gt; Configuration file for the destination backend&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;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;Bash&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-bash&#34;&gt;tempo-cli migrate tenant --source-config source.yaml --config-file dest.yaml my-tenant my-other-tenant&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;h2 id=&#34;migrate-overrides-config-command&#34;&gt;Migrate overrides config command&lt;/h2&gt;
&lt;p&gt;Migrate overrides config from inline format (legacy) to idented YAML format (new).&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;Bash&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-bash&#34;&gt;tempo-cli migrate overrides-config &amp;lt;source config file&amp;gt;&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Arguments:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;source config file&lt;/code&gt; Configuration file to migrate&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Options:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;--config-dest &amp;lt;value&amp;gt;&lt;/code&gt; Destination file for the migrated config. If not specified, config is printed to stdout.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;--overrides-dest &amp;lt;value&amp;gt;&lt;/code&gt; Destination file for the migrated overrides. If not specified, overrides are printed to stdout.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;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;Bash&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-bash&#34;&gt;tempo-cli migrate overrides-config config.yaml --config-dest config-tmp.yaml --overrides-dest overrides-tmp.yaml&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;h2 id=&#34;analyse-block&#34;&gt;Analyse block&lt;/h2&gt;
&lt;!-- Note that the command uses analyse and not analyze --&gt;
&lt;p&gt;Analyses a block and outputs a summary of the block&amp;rsquo;s generic attributes.&lt;/p&gt;
&lt;p&gt;It&amp;rsquo;s of particular use when trying to determine candidates for dedicated attribute columns in vParquet3&#43;.
The output includes span, resource, and event attributes with cardinality and size information.&lt;/p&gt;
&lt;p&gt;Arguments:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;tenant-id&lt;/code&gt; The tenant ID. Use &lt;code&gt;single-tenant&lt;/code&gt; for single tenant setups.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;block-id&lt;/code&gt; The block ID as UUID string.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Options:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;#backend-options&#34;&gt;Backend options&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;--num-attr &amp;lt;value&amp;gt;&lt;/code&gt; Number of attributes to output (default: 15)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;--num-int-attr &amp;lt;value&amp;gt;&lt;/code&gt; Number of integer attributes to display. If set to 0, uses the &lt;code&gt;--num-attr&lt;/code&gt; value (default: 5)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;--blob-threshold &amp;lt;value&amp;gt;&lt;/code&gt; Mark attributes as blob candidates when their dictionary size per row group exceeds this value. Set to 0 to disable. (default: 4MiB)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;--include-well-known&lt;/code&gt; Include well-known attributes in the analysis. Enable when generating dedicated columns for vParquet5 or higher. (default: false)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;--generate-jsonnet&lt;/code&gt; Generate Jsonnet overrides for dedicated columns&lt;/li&gt;
&lt;li&gt;&lt;code&gt;--generate-cli-args&lt;/code&gt; Generate command-line arguments for the parquet conversion command&lt;/li&gt;
&lt;li&gt;&lt;code&gt;--int-percent-threshold &amp;lt;value&amp;gt;&lt;/code&gt; Threshold for integer attributes in dedicated columns (default: 0.05)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;--simple-summary&lt;/code&gt; Print only a single line of top attributes (default: false)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;--print-full-summary&lt;/code&gt; Print full summary of the analysed block (default: true)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;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;Bash&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-bash&#34;&gt;tempo-cli analyse block --backend=local --bucket=./cmd/tempo-cli/test-data/ single-tenant b18beca6-4d7f-4464-9f72-f343e688a4a0&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Example with blob detection:&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;Bash&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-bash&#34;&gt;tempo-cli analyse block --blob-threshold=4MiB --generate-jsonnet --backend=local --bucket=./cmd/tempo-cli/test-data/ single-tenant b18beca6-4d7f-4464-9f72-f343e688a4a0&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;h2 id=&#34;analyse-blocks&#34;&gt;Analyse blocks&lt;/h2&gt;
&lt;p&gt;Analyses all blocks in a given time range and outputs a summary of the blocks&amp;rsquo; generic attributes.&lt;/p&gt;
&lt;p&gt;It&amp;rsquo;s of particular use when trying to determine candidates for dedicated attribute columns in vParquet3&#43;.
The output includes span, resource, and event attributes with cardinality and size information.&lt;/p&gt;
&lt;p&gt;Arguments:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;tenant-id&lt;/code&gt; The tenant ID. Use &lt;code&gt;single-tenant&lt;/code&gt; for single-tenant setups.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Options:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;#backend-options&#34;&gt;Backend options&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;--num-attr &amp;lt;value&amp;gt;&lt;/code&gt; Number of attributes to output (default: 15)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;--num-int-attr &amp;lt;value&amp;gt;&lt;/code&gt; Number of integer attributes to display. If set to 0, uses the &lt;code&gt;--num-attr&lt;/code&gt; value (default: 5)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;--min-compaction-level &amp;lt;value&amp;gt;&lt;/code&gt; Minimum compaction level to include in the analysis (default: 3)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;--max-blocks &amp;lt;value&amp;gt;&lt;/code&gt; Maximum number of blocks to analyze (default: 10)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;--max-start-time &amp;lt;value&amp;gt;&lt;/code&gt; Oldest start time for a block to be processed. RFC3339 format (default: disabled)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;--min-start-time &amp;lt;value&amp;gt;&lt;/code&gt; Newest start time for a block to be processed. RFC3339 format (default: disabled)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;--blob-threshold &amp;lt;value&amp;gt;&lt;/code&gt; Mark attributes as blob candidates when their dictionary size per row group exceeds this value. Set to 0 to disable. (default: 4MiB)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;--include-well-known&lt;/code&gt; Include well-known attributes in the analysis. (default: false)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;--jsonnet&lt;/code&gt; Generate Jsonnet overrides for dedicated columns&lt;/li&gt;
&lt;li&gt;&lt;code&gt;--cli&lt;/code&gt; Generate command-line arguments for the parquet conversion command&lt;/li&gt;
&lt;li&gt;&lt;code&gt;--int-percent-threshold &amp;lt;value&amp;gt;&lt;/code&gt; Threshold for integer attributes in dedicated columns (default: 0.05)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;--simple-summary&lt;/code&gt; Print only a single line of top attributes (default: false)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;--print-full-summary&lt;/code&gt; Print full summary of the analysed block (default: true)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;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;Bash&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-bash&#34;&gt;tempo-cli analyse blocks --backend=local --bucket=./cmd/tempo-cli/test-data/ single-tenant&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Example with blob detection and Jsonnet output:&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;Bash&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-bash&#34;&gt;tempo-cli analyse blocks --blob-threshold=4MiB --jsonnet --backend=local --bucket=./cmd/tempo-cli/test-data/ single-tenant&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;h2 id=&#34;drop-traces-by-id&#34;&gt;Drop traces by ID&lt;/h2&gt;
&lt;p&gt;Rewrites all blocks for a tenant that contain a specific trace IDs. The traces are dropped from
the new blocks and the rewritten blocks are marked compacted so they will be cleaned up.&lt;/p&gt;
&lt;p&gt;Arguments:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;tenant-id&lt;/code&gt; The tenant ID. Use &lt;code&gt;single-tenant&lt;/code&gt; for single tenant setups.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;trace-ids&lt;/code&gt; The comma-separated trace IDs to drop (also supports single trace ID)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Options:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;#backend-options&#34;&gt;Backend options&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;--drop-traces&lt;/code&gt; By default, this command runs in dry run mode. Supplying this argument causes it to actually rewrite blocks with the traces dropped.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;examples&#34;&gt;Examples&lt;/h3&gt;
&lt;p&gt;Drop one trace:&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;Bash&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-bash&#34;&gt;tempo-cli rewrite-blocks drop-trace --backend=local --bucket=./cmd/tempo-cli/test-data/ single-tenant 04d5f549746c96e4f3daed6202571db2&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Drop multiple traces:&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;Bash&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-bash&#34;&gt;tempo-cli rewrite-blocks drop-trace --backend=local --bucket=./cmd/tempo-cli/test-data/ single-tenant 04d5f549746c96e4f3daed6202571db2,111fa1850042aea83c17cd7e674210b8&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
]]></content><description>&lt;h1 id="tempo-cli">Tempo CLI&lt;/h1>
&lt;p>Tempo CLI is a separate executable that contains utility functions related to the Tempo software.
Although it&amp;rsquo;s not required for a working installation, Tempo CLI can be helpful for deeper analysis or for troubleshooting.&lt;/p></description></item><item><title>Apache Parquet schema</title><link>https://grafana.com/docs/tempo/v2.10.x/operations/schema/</link><pubDate>Thu, 09 Apr 2026 14:59:14 +0000</pubDate><guid>https://grafana.com/docs/tempo/v2.10.x/operations/schema/</guid><content><![CDATA[&lt;h1 id=&#34;apache-parquet-schema&#34;&gt;Apache Parquet schema&lt;/h1&gt;
&lt;!-- vale Grafana.GoogleSpacing = NO --&gt;
&lt;!-- vale Grafana.We = NO --&gt;
&lt;!-- vale Grafana.GooglePassive = NO --&gt;
&lt;!-- vale Grafana.GoogleWill = NO --&gt;
&lt;p&gt;Starting with Tempo 2.0, Apache Parquet is used as the default column-formatted block format.
Refer to the &lt;a href=&#34;../../configuration/parquet/&#34;&gt;Parquet configuration options&lt;/a&gt; for more information.&lt;/p&gt;
&lt;p&gt;This document describes the schema used with the Parquet block format.&lt;/p&gt;
&lt;h2 id=&#34;version-applicability&#34;&gt;Version applicability&lt;/h2&gt;
&lt;p&gt;Tempo 2.10 defaults to the vParquet4 schema. vParquet5 is production-ready and differs in some schema details.
Unless otherwise noted, the sections below describe vParquet4.&lt;/p&gt;
&lt;p&gt;The following sections apply to both vParquet4 and vParquet5:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Fully nested versus span-oriented schema&lt;/li&gt;
&lt;li&gt;Static vs dynamic columns (see vParquet5 differences for changes to dedicated columns)&lt;/li&gt;
&lt;li&gt;Compression and encoding&lt;/li&gt;
&lt;li&gt;Bloom filters&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;fully-nested-versus-span-oriented-schema&#34;&gt;Fully nested versus span-oriented schema&lt;/h2&gt;
&lt;p&gt;There are two overall approaches to a columnar schema: fully nested or span-oriented.
Span-oriented means a flattened schema where traces are destructured into rows of spans.
A fully nested schema means the current trace structures such as Resource/Scope/Spans/Events are preserved (nested data is natively supported in Parquet).
In both cases, individual leaf values such as span name and duration are individual columns.&lt;/p&gt;
&lt;p&gt;We chose the nested schema for several reasons:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The block size is much smaller for the nested schema. This is due to the high data duplication incurred when flattening resource-level attributes such as &lt;code&gt;service.name&lt;/code&gt; to each individual span.&lt;/li&gt;
&lt;li&gt;A flat schema is not truly &amp;ldquo;flat&amp;rdquo; because each span still contains nested data such as attributes and events.&lt;/li&gt;
&lt;li&gt;Nested schema is much faster to search for resource-level attributes because the resource-level columns are very small (1 row for each batch).&lt;/li&gt;
&lt;li&gt;Translation to and from the OpenTelemetry Protocol Specification (OTLP) is straightforward.&lt;/li&gt;
&lt;li&gt;Easily add computed columns (for example, trace duration) at multiple levels such as per-trace, per-batch, etc.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;static-vs-dynamic-columns&#34;&gt;Static vs dynamic columns&lt;/h2&gt;
&lt;p&gt;Dynamic vs static columns add another layer to the schema.
A dynamic schema stores each attribute such as &lt;code&gt;service.name&lt;/code&gt; and &lt;code&gt;http.status_code&lt;/code&gt; as its own column and the columns in each parquet file can be different.
A static schema is unresponsive to the shape of the data, and all attributes are stored in generic key/value containers.&lt;/p&gt;
&lt;p&gt;The dynamic schema is the ultimate dream for a columnar format but it is too complex for a first release.
However, the benefits of that approach are also too good to pass up, so we propose a hybrid approach.
It is primarily a static schema but with some dynamic columns extracted from trace data based on some heuristics of frequently queried attributes.
We plan to continue investing in this direction to implement a fully dynamic schema where trace attributes are blown out into independent Parquet columns at runtime.&lt;/p&gt;
&lt;p&gt;For more information, refer to the &lt;a href=&#34;https://github.com/grafana/tempo/blob/main/docs/design-proposals/2022-04%20Parquet.md&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;Parquet design document&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&#34;schema-details&#34;&gt;Schema details&lt;/h2&gt;
&lt;p&gt;The adopted Parquet schema is mostly a direct translation of OTLP but with some key differences.&lt;/p&gt;
&lt;p&gt;The table below uses these abbreviations:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;rs&lt;/code&gt; - resource spans&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ss&lt;/code&gt; - scope spans&lt;/li&gt;
&lt;/ul&gt;
&lt;!-- vale Grafana.GoogleSpacing = NO --&gt;
&lt;section class=&#34;expand-table-wrapper&#34;&gt;&lt;div class=&#34;button-div&#34;&gt;
      &lt;button class=&#34;expand-table-btn&#34;&gt;Expand table&lt;/button&gt;
    &lt;/div&gt;&lt;div class=&#34;responsive-table-wrapper&#34;&gt;
    &lt;table&gt;
      &lt;thead&gt;
          &lt;tr&gt;
              &lt;th style=&#34;text-align: left&#34;&gt;&lt;/th&gt;
              &lt;th style=&#34;text-align: left&#34;&gt;&lt;/th&gt;
              &lt;th style=&#34;text-align: left&#34;&gt;&lt;/th&gt;
          &lt;/tr&gt;
      &lt;/thead&gt;
      &lt;tbody&gt;
          &lt;tr&gt;
              &lt;td style=&#34;text-align: left&#34;&gt;Name&lt;/td&gt;
              &lt;td style=&#34;text-align: left&#34;&gt;Type&lt;/td&gt;
              &lt;td style=&#34;text-align: left&#34;&gt;Description&lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
              &lt;td style=&#34;text-align: left&#34;&gt;TraceID&lt;/td&gt;
              &lt;td style=&#34;text-align: left&#34;&gt;byte array&lt;/td&gt;
              &lt;td style=&#34;text-align: left&#34;&gt;The trace ID in 16-byte binary form.&lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
              &lt;td style=&#34;text-align: left&#34;&gt;TraceIDText&lt;/td&gt;
              &lt;td style=&#34;text-align: left&#34;&gt;string&lt;/td&gt;
              &lt;td style=&#34;text-align: left&#34;&gt;The trace ID in hexadecimal text form.&lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
              &lt;td style=&#34;text-align: left&#34;&gt;StartTimeUnixNano&lt;/td&gt;
              &lt;td style=&#34;text-align: left&#34;&gt;int64&lt;/td&gt;
              &lt;td style=&#34;text-align: left&#34;&gt;Start time of the first span in the trace, in nanoseconds since unix epoch.&lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
              &lt;td style=&#34;text-align: left&#34;&gt;EndTimeUnixNano&lt;/td&gt;
              &lt;td style=&#34;text-align: left&#34;&gt;int64&lt;/td&gt;
              &lt;td style=&#34;text-align: left&#34;&gt;End time of the last span in the trace, in nanoseconds since unix epoch.&lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
              &lt;td style=&#34;text-align: left&#34;&gt;DurationNano&lt;/td&gt;
              &lt;td style=&#34;text-align: left&#34;&gt;int64&lt;/td&gt;
              &lt;td style=&#34;text-align: left&#34;&gt;Total trace duration in nanoseconds, computed as difference between EndTimeUnixNano and StartTimeUnixNano.&lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
              &lt;td style=&#34;text-align: left&#34;&gt;RootServiceName&lt;/td&gt;
              &lt;td style=&#34;text-align: left&#34;&gt;string&lt;/td&gt;
              &lt;td style=&#34;text-align: left&#34;&gt;The resource-level &lt;code&gt;service.name&lt;/code&gt; attribute (rs.Resource.ServiceName) from the root span of the trace if one exists, else empty string.&lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
              &lt;td style=&#34;text-align: left&#34;&gt;RootSpanName&lt;/td&gt;
              &lt;td style=&#34;text-align: left&#34;&gt;string&lt;/td&gt;
              &lt;td style=&#34;text-align: left&#34;&gt;The name (rs.ss.Spans.Name) of the root span if one exists, else empty string.&lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
              &lt;td style=&#34;text-align: left&#34;&gt;ServiceStats&lt;/td&gt;
              &lt;td style=&#34;text-align: left&#34;&gt;map&lt;/td&gt;
              &lt;td style=&#34;text-align: left&#34;&gt;Per-service counts keyed by service name. Values include span count and error count.&lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
              &lt;td style=&#34;text-align: left&#34;&gt;rs&lt;/td&gt;
              &lt;td style=&#34;text-align: left&#34;&gt;&lt;/td&gt;
              &lt;td style=&#34;text-align: left&#34;&gt;Short-hand for ResourceSpans&lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
              &lt;td style=&#34;text-align: left&#34;&gt;rs.Resource.ServiceName&lt;/td&gt;
              &lt;td style=&#34;text-align: left&#34;&gt;string&lt;/td&gt;
              &lt;td style=&#34;text-align: left&#34;&gt;A dedicated column for the resource-level &lt;code&gt;service.name&lt;/code&gt; attribute if present. &lt;a href=&#34;https://opentelemetry.io/docs/reference/specification/resource/semantic_conventions/#service&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;https://opentelemetry.io/docs/reference/specification/resource/semantic_conventions/#service&lt;/a&gt;&lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
              &lt;td style=&#34;text-align: left&#34;&gt;rs.Resource.Cluster&lt;/td&gt;
              &lt;td style=&#34;text-align: left&#34;&gt;string&lt;/td&gt;
              &lt;td style=&#34;text-align: left&#34;&gt;A dedicated column for the resource-level &lt;code&gt;cluster&lt;/code&gt; attribute if present and of string type. Values of other types will be stored in the generic attribute columns.&lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
              &lt;td style=&#34;text-align: left&#34;&gt;rs.Resource.Namespace&lt;/td&gt;
              &lt;td style=&#34;text-align: left&#34;&gt;string&lt;/td&gt;
              &lt;td style=&#34;text-align: left&#34;&gt;A dedicated column for the resource-level &lt;code&gt;namespace&lt;/code&gt; attribute if present and of string type. Values of other types will be stored in the generic attribute columns.&lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
              &lt;td style=&#34;text-align: left&#34;&gt;rs.Resource.Pod&lt;/td&gt;
              &lt;td style=&#34;text-align: left&#34;&gt;string&lt;/td&gt;
              &lt;td style=&#34;text-align: left&#34;&gt;A dedicated column for the resource-level &lt;code&gt;pod&lt;/code&gt; attribute if present and of string type. Values of other types will be stored in the generic attribute columns.&lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
              &lt;td style=&#34;text-align: left&#34;&gt;rs.Resource.Container&lt;/td&gt;
              &lt;td style=&#34;text-align: left&#34;&gt;string&lt;/td&gt;
              &lt;td style=&#34;text-align: left&#34;&gt;A dedicated column for the resource-level &lt;code&gt;container&lt;/code&gt; attribute if present and of string type. Values of other types will be stored in the generic attribute columns.&lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
              &lt;td style=&#34;text-align: left&#34;&gt;rs.Resource.K8sClusterName&lt;/td&gt;
              &lt;td style=&#34;text-align: left&#34;&gt;string&lt;/td&gt;
              &lt;td style=&#34;text-align: left&#34;&gt;A dedicated column for the resource-level &lt;code&gt;k8s.cluster.name&lt;/code&gt; attribute if present and of string type. Values of other types will be stored in the generic attribute columns. &lt;a href=&#34;https://opentelemetry.io/docs/reference/specification/resource/semantic_conventions/k8s/#cluster&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;https://opentelemetry.io/docs/reference/specification/resource/semantic_conventions/k8s/#cluster&lt;/a&gt;&lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
              &lt;td style=&#34;text-align: left&#34;&gt;rs.Resource.K8sNamespaceName&lt;/td&gt;
              &lt;td style=&#34;text-align: left&#34;&gt;string&lt;/td&gt;
              &lt;td style=&#34;text-align: left&#34;&gt;A dedicated column for the resource-level &lt;code&gt;k8s.namespace.name&lt;/code&gt; attribute if present and of string type. Values of other types will be stored in the generic attribute columns. &lt;a href=&#34;https://opentelemetry.io/docs/reference/specification/resource/semantic_conventions/k8s/#namespace&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;https://opentelemetry.io/docs/reference/specification/resource/semantic_conventions/k8s/#namespace&lt;/a&gt;&lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
              &lt;td style=&#34;text-align: left&#34;&gt;rs.Resource.K8sPodName&lt;/td&gt;
              &lt;td style=&#34;text-align: left&#34;&gt;string&lt;/td&gt;
              &lt;td style=&#34;text-align: left&#34;&gt;A dedicated column for the resource-level &lt;code&gt;k8s.pod.name&lt;/code&gt; attribute if present and of string type. Values of other types will be stored in the generic attribute columns. &lt;a href=&#34;https://opentelemetry.io/docs/reference/specification/resource/semantic_conventions/k8s/#pod&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;https://opentelemetry.io/docs/reference/specification/resource/semantic_conventions/k8s/#pod&lt;/a&gt;&lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
              &lt;td style=&#34;text-align: left&#34;&gt;rs.Resource.K8sContainerName&lt;/td&gt;
              &lt;td style=&#34;text-align: left&#34;&gt;string&lt;/td&gt;
              &lt;td style=&#34;text-align: left&#34;&gt;A dedicated column for the resource-level &lt;code&gt;k8s.container.name&lt;/code&gt; attribute if present and of string type. Values of other types will be stored in the generic attribute columns. &lt;a href=&#34;https://opentelemetry.io/docs/reference/specification/resource/semantic_conventions/k8s/#container&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;https://opentelemetry.io/docs/reference/specification/resource/semantic_conventions/k8s/#container&lt;/a&gt;&lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
              &lt;td style=&#34;text-align: left&#34;&gt;rs.Resource.DroppedAttributesCount&lt;/td&gt;
              &lt;td style=&#34;text-align: left&#34;&gt;int&lt;/td&gt;
              &lt;td style=&#34;text-align: left&#34;&gt;Number of resource attributes that were dropped.&lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
              &lt;td style=&#34;text-align: left&#34;&gt;rs.Resource.Attrs.Key&lt;/td&gt;
              &lt;td style=&#34;text-align: left&#34;&gt;string&lt;/td&gt;
              &lt;td style=&#34;text-align: left&#34;&gt;All resource attributes that do not have a dedicated column are stored as a key value pair in these columns. The Key column stores the name, and then one of the Value columns is populated according to the attribute&amp;rsquo;s data type. The other value columns will contain null.&lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
              &lt;td style=&#34;text-align: left&#34;&gt;rs.Resource.Attrs.IsArray&lt;/td&gt;
              &lt;td style=&#34;text-align: left&#34;&gt;bool&lt;/td&gt;
              &lt;td style=&#34;text-align: left&#34;&gt;Indicates if the attribute is stored as an array.&lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
              &lt;td style=&#34;text-align: left&#34;&gt;rs.Resource.Attrs.Value&lt;/td&gt;
              &lt;td style=&#34;text-align: left&#34;&gt;string&lt;/td&gt;
              &lt;td style=&#34;text-align: left&#34;&gt;The attribute value if string type (or array of strings), else null.&lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
              &lt;td style=&#34;text-align: left&#34;&gt;rs.Resource.Attrs.ValueInt&lt;/td&gt;
              &lt;td style=&#34;text-align: left&#34;&gt;int&lt;/td&gt;
              &lt;td style=&#34;text-align: left&#34;&gt;The attribute value if integer type (or array of integers), else null.&lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
              &lt;td style=&#34;text-align: left&#34;&gt;rs.Resource.Attrs.ValueDouble&lt;/td&gt;
              &lt;td style=&#34;text-align: left&#34;&gt;float&lt;/td&gt;
              &lt;td style=&#34;text-align: left&#34;&gt;The attribute value if float type (or array of floats), else null.&lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
              &lt;td style=&#34;text-align: left&#34;&gt;rs.Resource.Attrs.ValueBool&lt;/td&gt;
              &lt;td style=&#34;text-align: left&#34;&gt;bool&lt;/td&gt;
              &lt;td style=&#34;text-align: left&#34;&gt;The attribute value if boolean type (or array of booleans), else null.&lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
              &lt;td style=&#34;text-align: left&#34;&gt;rs.Resource.Attrs.ValueUnsupported&lt;/td&gt;
              &lt;td style=&#34;text-align: left&#34;&gt;string&lt;/td&gt;
              &lt;td style=&#34;text-align: left&#34;&gt;JSON-encoded AnyValue for unsupported or mixed-type values.&lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
              &lt;td style=&#34;text-align: left&#34;&gt;rs.Resource.DedicatedAttributes&lt;/td&gt;
              &lt;td style=&#34;text-align: left&#34;&gt;&lt;/td&gt;
              &lt;td style=&#34;text-align: left&#34;&gt;Group containing spares for dedicated attribute columns with resource scope.&lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
              &lt;td style=&#34;text-align: left&#34;&gt;rs.Resource.DedicatedAttributes.String01 &amp;hellip; String10&lt;/td&gt;
              &lt;td style=&#34;text-align: left&#34;&gt;string&lt;/td&gt;
              &lt;td style=&#34;text-align: left&#34;&gt;10 spare columns for dedicated attribute columns.&lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
              &lt;td style=&#34;text-align: left&#34;&gt;rs.ss&lt;/td&gt;
              &lt;td style=&#34;text-align: left&#34;&gt;&lt;/td&gt;
              &lt;td style=&#34;text-align: left&#34;&gt;Shorthand for ResourceSpans.ScopeSpans&lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
              &lt;td style=&#34;text-align: left&#34;&gt;rs.ss.Scope&lt;/td&gt;
              &lt;td style=&#34;text-align: left&#34;&gt;&lt;/td&gt;
              &lt;td style=&#34;text-align: left&#34;&gt;Shorthand for ResourceSpans.ScopeSpans.Scope&lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
              &lt;td style=&#34;text-align: left&#34;&gt;rs.ss.Scope.Name&lt;/td&gt;
              &lt;td style=&#34;text-align: left&#34;&gt;string&lt;/td&gt;
              &lt;td style=&#34;text-align: left&#34;&gt;Scope name if present, else empty string. &lt;a href=&#34;https://opentelemetry.io/docs/specs/otel/glossary/#instrumentation-scope&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;https://opentelemetry.io/docs/specs/otel/glossary/#instrumentation-scope&lt;/a&gt;&lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
              &lt;td style=&#34;text-align: left&#34;&gt;rs.ss.Scope.Version&lt;/td&gt;
              &lt;td style=&#34;text-align: left&#34;&gt;string&lt;/td&gt;
              &lt;td style=&#34;text-align: left&#34;&gt;The Scope version if present, else empty string. &lt;a href=&#34;https://opentelemetry.io/docs/specs/otel/glossary/#instrumentation-scope&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;https://opentelemetry.io/docs/specs/otel/glossary/#instrumentation-scope&lt;/a&gt;&lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
              &lt;td style=&#34;text-align: left&#34;&gt;rs.ss.Scope.Attrs&lt;/td&gt;
              &lt;td style=&#34;text-align: left&#34;&gt;&lt;/td&gt;
              &lt;td style=&#34;text-align: left&#34;&gt;Scope attributes, using the same columns as rs.Resource.Attrs.*&lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
              &lt;td style=&#34;text-align: left&#34;&gt;rs.ss.Scope.DroppedAttributesCount&lt;/td&gt;
              &lt;td style=&#34;text-align: left&#34;&gt;int&lt;/td&gt;
              &lt;td style=&#34;text-align: left&#34;&gt;Number of scope attributes that were dropped.&lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
              &lt;td style=&#34;text-align: left&#34;&gt;rs.ss.Spans.SpanID&lt;/td&gt;
              &lt;td style=&#34;text-align: left&#34;&gt;byte array&lt;/td&gt;
              &lt;td style=&#34;text-align: left&#34;&gt;Span unique ID.&lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
              &lt;td style=&#34;text-align: left&#34;&gt;rs.ss.Spans.ParentSpanID&lt;/td&gt;
              &lt;td style=&#34;text-align: left&#34;&gt;byte array&lt;/td&gt;
              &lt;td style=&#34;text-align: left&#34;&gt;The unique ID of the span&amp;rsquo;s parent. For root spans without a parent this is null.&lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
              &lt;td style=&#34;text-align: left&#34;&gt;rs.ss.Spans.ParentID&lt;/td&gt;
              &lt;td style=&#34;text-align: left&#34;&gt;int32&lt;/td&gt;
              &lt;td style=&#34;text-align: left&#34;&gt;Trace local numeric parent ID.&lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
              &lt;td style=&#34;text-align: left&#34;&gt;rs.ss.Spans.NestedSetLeft&lt;/td&gt;
              &lt;td style=&#34;text-align: left&#34;&gt;int32&lt;/td&gt;
              &lt;td style=&#34;text-align: left&#34;&gt;Left bound of the nested set model. Also used as a trace local numeric span ID.&lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
              &lt;td style=&#34;text-align: left&#34;&gt;rs.ss.Spans.NestedSetRight&lt;/td&gt;
              &lt;td style=&#34;text-align: left&#34;&gt;int32&lt;/td&gt;
              &lt;td style=&#34;text-align: left&#34;&gt;Right bound of the nested set model.&lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
              &lt;td style=&#34;text-align: left&#34;&gt;rs.ss.Spans.Name&lt;/td&gt;
              &lt;td style=&#34;text-align: left&#34;&gt;string&lt;/td&gt;
              &lt;td style=&#34;text-align: left&#34;&gt;Span name.&lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
              &lt;td style=&#34;text-align: left&#34;&gt;rs.ss.Spans.StartTimeUnixNano&lt;/td&gt;
              &lt;td style=&#34;text-align: left&#34;&gt;int64&lt;/td&gt;
              &lt;td style=&#34;text-align: left&#34;&gt;Start time the span in nanoseconds since unix epoch.&lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
              &lt;td style=&#34;text-align: left&#34;&gt;rs.ss.Spans.DurationNano&lt;/td&gt;
              &lt;td style=&#34;text-align: left&#34;&gt;int64&lt;/td&gt;
              &lt;td style=&#34;text-align: left&#34;&gt;Span duration in nanoseconds.&lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
              &lt;td style=&#34;text-align: left&#34;&gt;rs.ss.Spans.Kind&lt;/td&gt;
              &lt;td style=&#34;text-align: left&#34;&gt;int&lt;/td&gt;
              &lt;td style=&#34;text-align: left&#34;&gt;The span&amp;rsquo;s kind. Defined values: 0. Unset; 1. Internal; 2. Server; 3. Client; 4. Producer; 5. Consumer; &lt;a href=&#34;https://opentelemetry.io/docs/reference/specification/trace/api/#spankind&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;https://opentelemetry.io/docs/reference/specification/trace/api/#spankind&lt;/a&gt;&lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
              &lt;td style=&#34;text-align: left&#34;&gt;rs.ss.Spans.StatusCode&lt;/td&gt;
              &lt;td style=&#34;text-align: left&#34;&gt;int&lt;/td&gt;
              &lt;td style=&#34;text-align: left&#34;&gt;The span status. Defined values: 0: Unset; 1: OK; 2: Error. &lt;a href=&#34;https://opentelemetry.io/docs/reference/specification/trace/api/#set-status&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;https://opentelemetry.io/docs/reference/specification/trace/api/#set-status&lt;/a&gt;&lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
              &lt;td style=&#34;text-align: left&#34;&gt;rs.ss.Spans.StatusMessage&lt;/td&gt;
              &lt;td style=&#34;text-align: left&#34;&gt;string&lt;/td&gt;
              &lt;td style=&#34;text-align: left&#34;&gt;Optional message to accompany Error status.&lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
              &lt;td style=&#34;text-align: left&#34;&gt;rs.ss.Spans.HttpMethod&lt;/td&gt;
              &lt;td style=&#34;text-align: left&#34;&gt;string&lt;/td&gt;
              &lt;td style=&#34;text-align: left&#34;&gt;A dedicated column for the span-level &lt;code&gt;http.method&lt;/code&gt; attribute if present and of string type, else null. Values of other types will be stored in the generic attribute columns. &lt;a href=&#34;https://opentelemetry.io/docs/reference/specification/trace/semantic_conventions/http/#common-attributes&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;https://opentelemetry.io/docs/reference/specification/trace/semantic_conventions/http/#common-attributes&lt;/a&gt;&lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
              &lt;td style=&#34;text-align: left&#34;&gt;rs.ss.Spans.HttpStatusCode&lt;/td&gt;
              &lt;td style=&#34;text-align: left&#34;&gt;int&lt;/td&gt;
              &lt;td style=&#34;text-align: left&#34;&gt;A dedicated column for the span-level &lt;code&gt;http.status_code&lt;/code&gt; attribute if present and of integer type, else null. Values of other types will be stored in the generic attribute columns. &lt;a href=&#34;https://opentelemetry.io/docs/reference/specification/trace/semantic_conventions/http/#common-attributes&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;https://opentelemetry.io/docs/reference/specification/trace/semantic_conventions/http/#common-attributes&lt;/a&gt;&lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
              &lt;td style=&#34;text-align: left&#34;&gt;rs.ss.Spans.HttpUrl&lt;/td&gt;
              &lt;td style=&#34;text-align: left&#34;&gt;string&lt;/td&gt;
              &lt;td style=&#34;text-align: left&#34;&gt;A dedicated column for the span-level &lt;code&gt;http.url&lt;/code&gt; attribute if present and of string type, else null. Values of other types will be stored in the generic attribute columns. &lt;a href=&#34;https://opentelemetry.io/docs/reference/specification/trace/semantic_conventions/http/#http-client&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;https://opentelemetry.io/docs/reference/specification/trace/semantic_conventions/http/#http-client&lt;/a&gt;&lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
              &lt;td style=&#34;text-align: left&#34;&gt;rs.ss.Spans.DroppedAttributesCount&lt;/td&gt;
              &lt;td style=&#34;text-align: left&#34;&gt;int&lt;/td&gt;
              &lt;td style=&#34;text-align: left&#34;&gt;Number of attributes that were dropped&lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
              &lt;td style=&#34;text-align: left&#34;&gt;rs.ss.Spans.Attrs&lt;/td&gt;
              &lt;td style=&#34;text-align: left&#34;&gt;&lt;/td&gt;
              &lt;td style=&#34;text-align: left&#34;&gt;Span attributes, using the same columns as rs.Resource.Attrs.*&lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
              &lt;td style=&#34;text-align: left&#34;&gt;rs.ss.Spans.DedicatedAttributes&lt;/td&gt;
              &lt;td style=&#34;text-align: left&#34;&gt;&lt;/td&gt;
              &lt;td style=&#34;text-align: left&#34;&gt;Group containing spares for dedicated attribute columns with span scope&lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
              &lt;td style=&#34;text-align: left&#34;&gt;rs.ss.Spans.DedicatedAttributes.String01 &amp;hellip; String10&lt;/td&gt;
              &lt;td style=&#34;text-align: left&#34;&gt;string&lt;/td&gt;
              &lt;td style=&#34;text-align: left&#34;&gt;10 spare columns used for dedicated attributes&lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
              &lt;td style=&#34;text-align: left&#34;&gt;rs.ss.Spans.DroppedEventsCount&lt;/td&gt;
              &lt;td style=&#34;text-align: left&#34;&gt;int&lt;/td&gt;
              &lt;td style=&#34;text-align: left&#34;&gt;The number of events that were dropped&lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
              &lt;td style=&#34;text-align: left&#34;&gt;rs.ss.Spans.Events.TimeSinceStartNano&lt;/td&gt;
              &lt;td style=&#34;text-align: left&#34;&gt;int64&lt;/td&gt;
              &lt;td style=&#34;text-align: left&#34;&gt;The event timestamp in nanoseconds, relative to the span start time.&lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
              &lt;td style=&#34;text-align: left&#34;&gt;rs.ss.Spans.Events.Name&lt;/td&gt;
              &lt;td style=&#34;text-align: left&#34;&gt;string&lt;/td&gt;
              &lt;td style=&#34;text-align: left&#34;&gt;The event name or message.&lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
              &lt;td style=&#34;text-align: left&#34;&gt;rs.ss.Spans.Events.DroppedAttributesCount&lt;/td&gt;
              &lt;td style=&#34;text-align: left&#34;&gt;int&lt;/td&gt;
              &lt;td style=&#34;text-align: left&#34;&gt;The number of event attributes that were dropped.&lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
              &lt;td style=&#34;text-align: left&#34;&gt;rs.ss.Spans.Events.Attrs&lt;/td&gt;
              &lt;td style=&#34;text-align: left&#34;&gt;&lt;/td&gt;
              &lt;td style=&#34;text-align: left&#34;&gt;Event attributes, using the same columns as rs.Resource.Attrs.*&lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
              &lt;td style=&#34;text-align: left&#34;&gt;rs.ss.Spans.DroppedLinksCount&lt;/td&gt;
              &lt;td style=&#34;text-align: left&#34;&gt;int&lt;/td&gt;
              &lt;td style=&#34;text-align: left&#34;&gt;The number of links that were dropped.&lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
              &lt;td style=&#34;text-align: left&#34;&gt;rs.ss.Spans.Links&lt;/td&gt;
              &lt;td style=&#34;text-align: left&#34;&gt;&lt;/td&gt;
              &lt;td style=&#34;text-align: left&#34;&gt;Repeated link records with TraceID, SpanID, TraceState, Attrs, and DroppedAttributesCount.&lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
              &lt;td style=&#34;text-align: left&#34;&gt;rs.ss.Spans.TraceState&lt;/td&gt;
              &lt;td style=&#34;text-align: left&#34;&gt;string&lt;/td&gt;
              &lt;td style=&#34;text-align: left&#34;&gt;The span&amp;rsquo;s TraceState value if present, else empty string. &lt;a href=&#34;https://opentelemetry.io/docs/reference/specification/trace/api/#tracestate&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;https://opentelemetry.io/docs/reference/specification/trace/api/#tracestate&lt;/a&gt;&lt;/td&gt;
          &lt;/tr&gt;
      &lt;/tbody&gt;
    &lt;/table&gt;
  &lt;/div&gt;
&lt;/section&gt;&lt;!-- vale Grafana.GoogleSpacing = YES --&gt;
&lt;p&gt;To increase the readability the table omits the groups &lt;code&gt;list.element&lt;/code&gt; that are added for nested list types in Parquet.
For maps (for example, ServiceStats), Parquet also inserts map-specific group levels that are omitted here.&lt;/p&gt;
&lt;div class=&#34;collapse&#34; x-data=&#34;app_collapse()&#34;&gt;
  &lt;button class=&#34;collapse-trigger&#34; @click=&#34;toggle()&#34;&gt;
    &lt;span class=&#34;body-large&#34;&gt;vParquet4 block schema example&lt;/span&gt;
    &lt;span class=&#34;collapse-trigger__icon&#34; :class=&#34;{ &#39;collapse-trigger__icon-open&#39; : open }&#34;&gt;
      
  &lt;svg width=&#34;27&#34; height=&#34;26&#34; viewBox=&#34;0 0 27 26&#34; fill=&#34;none&#34; xmlns=&#34;http://www.w3.org/2000/svg&#34;&gt;
&lt;path opacity=&#34;0.2&#34; d=&#34;M1.73047 12.8359C1.73047 19.4634 7.10305 24.8359 13.7305 24.8359C20.3579 24.8359 25.7305 19.4634 25.7305 12.8359C25.7305 6.20852 20.3579 0.835937 13.7305 0.835937C7.10305 0.835937 1.73047 6.20852 1.73047 12.8359Z&#34; stroke=&#34;black&#34; stroke-width=&#34;1.5&#34; stroke-linecap=&#34;round&#34; stroke-linejoin=&#34;round&#34;/&gt;
&lt;path d=&#34;M18.2344 12.8359L9.23438 12.8359&#34; stroke=&#34;black&#34; stroke-width=&#34;1.5&#34; stroke-linecap=&#34;round&#34; stroke-linejoin=&#34;round&#34;/&gt;
&lt;path d=&#34;M13.7344 8.33594L13.7344 17.3359&#34; stroke=&#34;black&#34; stroke-width=&#34;1.5&#34; stroke-linecap=&#34;round&#34; stroke-linejoin=&#34;round&#34;/&gt;
&lt;/svg&gt;


    &lt;/span&gt;
  &lt;/button&gt;
  &lt;div class=&#34;collapse-content&#34; x-ref=&#34;content&#34; hidden=&#34;until-found&#34;&gt;
    &lt;div class=&#34;collapse-content__inner&#34; x-ref=&#34;content-inner&#34;&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;message Trace {
  required binary TraceID;
  required binary TraceIDText (STRING);
  required int64 StartTimeUnixNano (INTEGER(64,false));
  required int64 EndTimeUnixNano (INTEGER(64,false));
  required int64 DurationNano (INTEGER(64,false));
  required binary RootServiceName (STRING);
  required binary RootSpanName (STRING);
  optional group ServiceStats (MAP) {
    repeated group key_value {
      required binary key (STRING);
      required group value {
        required int32 SpanCount (INTEGER(32,false));
        required int32 ErrorCount (INTEGER(32,false));
      }
    }
  }
  required group rs (LIST) {
    repeated group list {
      required group element {
        required group Resource {
          required group Attrs (LIST) {
            repeated group list {
              required group element {
                required binary Key (STRING);
                required boolean IsArray;
                required group Value (LIST) {
                  repeated group list {
                    required binary element (STRING);
                  }
                }
                required group ValueInt (LIST) {
                  repeated group list {
                    required int64 element (INTEGER(64,true));
                  }
                }
                required group ValueDouble (LIST) {
                  repeated group list {
                    required double element;
                  }
                }
                required group ValueBool (LIST) {
                  repeated group list {
                    required boolean element;
                  }
                }
                optional binary ValueUnsupported (STRING);
              }
            }
          }
          required int32 DroppedAttributesCount (INTEGER(32,true));
          required binary ServiceName (STRING);
          optional binary Cluster (STRING);
          optional binary Namespace (STRING);
          optional binary Pod (STRING);
          optional binary Container (STRING);
          optional binary K8sClusterName (STRING);
          optional binary K8sNamespaceName (STRING);
          optional binary K8sPodName (STRING);
          optional binary K8sContainerName (STRING);
          required group DedicatedAttributes {
            optional binary String01 (STRING);
            optional binary String02 (STRING);
            optional binary String03 (STRING);
            optional binary String04 (STRING);
            optional binary String05 (STRING);
            optional binary String06 (STRING);
            optional binary String07 (STRING);
            optional binary String08 (STRING);
            optional binary String09 (STRING);
            optional binary String10 (STRING);
          }
        }
        required group ss (LIST) {
          repeated group list {
            required group element {
              required group Scope {
                required binary Name (STRING);
                required binary Version (STRING);
                required group Attrs (LIST) {
                  repeated group list {
                    required group element {
                      required binary Key (STRING);
                      required boolean IsArray;
                      required group Value (LIST) {
                        repeated group list {
                          required binary element (STRING);
                        }
                      }
                      required group ValueInt (LIST) {
                        repeated group list {
                          required int64 element (INTEGER(64,true));
                        }
                      }
                      required group ValueDouble (LIST) {
                        repeated group list {
                          required double element;
                        }
                      }
                      required group ValueBool (LIST) {
                        repeated group list {
                          required boolean element;
                        }
                      }
                      optional binary ValueUnsupported (STRING);
                    }
                  }
                }
                required int32 DroppedAttributesCount (INTEGER(32,true));
              }
              required group Spans (LIST) {
                repeated group list {
                  required group element {
                    required binary SpanID;
                    required binary ParentSpanID;
                    required int32 ParentID (INTEGER(32,true));
                    required int32 NestedSetLeft (INTEGER(32,true));
                    required int32 NestedSetRight (INTEGER(32,true));
                    required binary Name (STRING);
                    required int64 Kind (INTEGER(64,true));
                    required binary TraceState (STRING);
                    required int64 StartTimeUnixNano (INTEGER(64,false));
                    required int64 DurationNano (INTEGER(64,false));
                    required int64 StatusCode (INTEGER(64,true));
                    required binary StatusMessage (STRING);
                    required group Attrs (LIST) {
                      repeated group list {
                        required group element {
                          required binary Key (STRING);
                          required boolean IsArray;
                          required group Value (LIST) {
                            repeated group list {
                              required binary element (STRING);
                            }
                          }
                          required group ValueInt (LIST) {
                            repeated group list {
                              required int64 element (INTEGER(64,true));
                            }
                          }
                          required group ValueDouble (LIST) {
                            repeated group list {
                              required double element;
                            }
                          }
                          required group ValueBool (LIST) {
                            repeated group list {
                              required boolean element;
                            }
                          }
                          optional binary ValueUnsupported (STRING);
                        }
                      }
                    }
                    required int32 DroppedAttributesCount (INTEGER(32,true));
                    required group Events (LIST) {
                      repeated group list {
                        required group element {
                          required int64 TimeSinceStartNano (INTEGER(64,false));
                          required binary Name (STRING);
                          required group Attrs (LIST) {
                            repeated group list {
                              required group element {
                                required binary Key (STRING);
                                required boolean IsArray;
                                required group Value (LIST) {
                                  repeated group list {
                                    required binary element (STRING);
                                  }
                                }
                                required group ValueInt (LIST) {
                                  repeated group list {
                                    required int64 element (INTEGER(64,true));
                                  }
                                }
                                required group ValueDouble (LIST) {
                                  repeated group list {
                                    required double element;
                                  }
                                }
                                required group ValueBool (LIST) {
                                  repeated group list {
                                    required boolean element;
                                  }
                                }
                                optional binary ValueUnsupported (STRING);
                              }
                            }
                          }
                          required int32 DroppedAttributesCount (INTEGER(32,true));
                        }
                      }
                    }
                    required int32 DroppedEventsCount (INTEGER(32,true));
                    required group Links (LIST) {
                      repeated group list {
                        required group element {
                          required binary TraceID;
                          required binary SpanID;
                          required binary TraceState (STRING);
                          required group Attrs (LIST) {
                            repeated group list {
                              required group element {
                                required binary Key (STRING);
                                required boolean IsArray;
                                required group Value (LIST) {
                                  repeated group list {
                                    required binary element (STRING);
                                  }
                                }
                                required group ValueInt (LIST) {
                                  repeated group list {
                                    required int64 element (INTEGER(64,true));
                                  }
                                }
                                required group ValueDouble (LIST) {
                                  repeated group list {
                                    required double element;
                                  }
                                }
                                required group ValueBool (LIST) {
                                  repeated group list {
                                    required boolean element;
                                  }
                                }
                                optional binary ValueUnsupported (STRING);
                              }
                            }
                          }
                          required int32 DroppedAttributesCount (INTEGER(32,true));
                        }
                      }
                    }
                    required int32 DroppedLinksCount (INTEGER(32,true));
                    optional binary HttpMethod (STRING);
                    optional binary HttpUrl (STRING);
                    optional int64 HttpStatusCode (INTEGER(64,true));
                    required group DedicatedAttributes {
                      optional binary String01 (STRING);
                      optional binary String02 (STRING);
                      optional binary String03 (STRING);
                      optional binary String04 (STRING);
                      optional binary String05 (STRING);
                      optional binary String06 (STRING);
                      optional binary String07 (STRING);
                      optional binary String08 (STRING);
                      optional binary String09 (STRING);
                      optional binary String10 (STRING);
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;For the authoritative schema, refer to &lt;code&gt;tempodb/encoding/vparquet4/schema.go&lt;/code&gt; and &lt;code&gt;tempodb/encoding/vparquet5/schema.go&lt;/code&gt;.&lt;/p&gt;
&lt;h3 id=&#34;summary-of-vparquet5-differences&#34;&gt;Summary of vParquet5 differences&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Resource-level dedicated columns (Cluster/Namespace/Pod/Container/K8s*) and span HTTP columns are removed; vParquet5 relies on dynamically assigned dedicated columns only.&lt;/li&gt;
&lt;li&gt;Dedicated attribute columns expand to include integer spares, array attributes, and optional blob configuration for selected columns.&lt;/li&gt;
&lt;li&gt;Additional fields exist for optimization, including span &lt;code&gt;ChildCount&lt;/code&gt;, rounded start time buckets, and trace-level &lt;code&gt;ServiceStats&lt;/code&gt; as a list with explicit service names.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;trace-level-attributes&#34;&gt;Trace-level attributes&lt;/h2&gt;
&lt;p&gt;For speed and ease-of-use, we are projecting several values to columns at the trace-level:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Trace ID - Don&amp;rsquo;t store on each span.&lt;/li&gt;
&lt;li&gt;Root service/span names/StartTimeUnixNano - These are selected properties of the root span in each trace (if there is one). These are used for displaying results in the Grafana UI. These properties are computed at ingest time and stored once for efficiency, so we don&amp;rsquo;t have to find the root span.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;DurationNano&lt;/code&gt; - The total trace duration, computed at ingest time. This powers the min/max duration filtering in the current Tempo search and is more efficient than scanning the spans duration column. However, it may go away with TraceQL or we could decide to change it to span-level duration filtering too.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ServiceStats&lt;/code&gt; - Per-service span and error counts for each trace.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;any-type-attributes&#34;&gt;&amp;ldquo;Any&amp;rdquo;-type Attributes&lt;/h2&gt;
&lt;p&gt;OTLP attributes have variable data types, which is simpler in formats like protocol-buffers, but doesn&amp;rsquo;t translate directly to Parquet.
Each column must have a concrete type.
There are several possibilities here but we chose to have optional values for each concrete type.
Unsupported or mixed-type values are stored as JSON-encoded AnyValue in &lt;code&gt;ValueUnsupported&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Only scalar values are stored in the dedicated attribute columns. Arrays and unsupported types remain in the generic attribute columns.&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;repeated group Attrs {
required binary Key (STRING);
required boolean IsArray;
repeated binary Value (STRING);
repeated int64 ValueInt (INTEGER(64,true));
repeated double ValueDouble;
repeated boolean ValueBool;
optional binary ValueUnsupported (STRING);
}&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;h2 id=&#34;compression-and-encoding&#34;&gt;Compression and encoding&lt;/h2&gt;
&lt;p&gt;Parquet has robust support for many compression algorithms and data encodings. We&amp;rsquo;ve found excellent combinations of storage size and performance with the following:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Snappy Compression - Enable on all columns&lt;/li&gt;
&lt;li&gt;Dictionary encoding - Enable on all string columns. Most strings are very repetitive so this works well to optimize storage size. However, you can greatly speed up search by inspecting the dictionary first and eliminating pages with no matches.&lt;/li&gt;
&lt;li&gt;Time and duration UNIX nanos - Delta encoding&lt;/li&gt;
&lt;li&gt;Rarely used columns such as &lt;code&gt;DroppedAttributesCount&lt;/code&gt; - These columns are usually all zeroes, RLE works well.&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&#34;bloom-filters&#34;&gt;Bloom filters&lt;/h3&gt;
&lt;p&gt;Parquet has native support for bloom filters. However, Tempo doesn&amp;rsquo;t use them at this time. Tempo already has sophisticated support for sharding and caching bloom filters.&lt;/p&gt;
&lt;!-- vale Grafana.GoogleSpacing = YES --&gt;
&lt;!-- vale Grafana.We = YES --&gt;
&lt;!-- vale Grafana.GooglePassive = YES --&gt;
&lt;!-- vale Grafana.GoogleWill = YES --&gt;
]]></content><description>&lt;h1 id="apache-parquet-schema">Apache Parquet schema&lt;/h1>
&lt;!-- vale Grafana.GoogleSpacing = NO -->
&lt;!-- vale Grafana.We = NO -->
&lt;!-- vale Grafana.GooglePassive = NO -->
&lt;!-- vale Grafana.GoogleWill = NO -->
&lt;p>Starting with Tempo 2.0, Apache Parquet is used as the default column-formatted block format.
Refer to the &lt;a href="../../configuration/parquet/">Parquet configuration options&lt;/a> for more information.&lt;/p></description></item><item><title>Manage authentication</title><link>https://grafana.com/docs/tempo/v2.10.x/operations/authentication/</link><pubDate>Thu, 09 Apr 2026 14:59:14 +0000</pubDate><guid>https://grafana.com/docs/tempo/v2.10.x/operations/authentication/</guid><content><![CDATA[&lt;h1 id=&#34;manage-authentication&#34;&gt;Manage authentication&lt;/h1&gt;
&lt;p&gt;Grafana Tempo does not come with any included authentication layer. You must run an authenticating reverse proxy in front of your services.&lt;/p&gt;
&lt;p&gt;We recommend that in all 
    &lt;a href=&#34;/docs/tempo/v2.10.x/setup/deployment/&#34;&gt;deployment modes&lt;/a&gt; you add a reverse proxy to be deployed in front of Tempo, to direct client API requests to the various components.&lt;/p&gt;
&lt;p&gt;A list of open-source reverse proxies you can use:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://docs.haproxy.org/&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;HAProxy&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://docs.nginx.com/nginx/&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;NGINX&lt;/a&gt; using their &lt;a href=&#34;https://docs.nginx.com/nginx/admin-guide/security-controls/configuring-http-basic-authentication/&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;guide on restricting access with HTTP basic authentication&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://oauth2-proxy.github.io/oauth2-proxy/&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;OAuth2 proxy&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.pomerium.com/docs&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;Pomerium&lt;/a&gt;, which has a &lt;a href=&#34;https://www.pomerium.com/docs/guides/grafana&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;guide for securing Grafana&lt;/a&gt;&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;When using Tempo in multi-tenant mode, Tempo requires the HTTP header
&lt;code&gt;X-Scope-OrgID&lt;/code&gt; to be set to a string identifying the tenant.
It&amp;rsquo;s assumed that clients setting &lt;code&gt;X-Scope-OrgID&lt;/code&gt; are trusted clients, and the responsibility of populating this value should be handled by the authenticating reverse proxy.
For more information, read the 
    &lt;a href=&#34;/docs/tempo/v2.10.x/operations/manage-advanced-systems/multitenancy/&#34;&gt;multi-tenancy&lt;/a&gt; documentation.&lt;/p&gt;&lt;/blockquote&gt;&lt;/div&gt;

]]></content><description>&lt;h1 id="manage-authentication">Manage authentication&lt;/h1>
&lt;p>Grafana Tempo does not come with any included authentication layer. You must run an authenticating reverse proxy in front of your services.&lt;/p>
&lt;p>We recommend that in all
&lt;a href="/docs/tempo/v2.10.x/setup/deployment/">deployment modes&lt;/a> you add a reverse proxy to be deployed in front of Tempo, to direct client API requests to the various components.&lt;/p></description></item></channel></rss>