<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Sampling on Grafana Labs</title><link>https://grafana.com/docs/tempo/v2.9.x/set-up-for-tracing/instrument-send/set-up-collector/tail-sampling/</link><description>Recent content in Sampling on Grafana Labs</description><generator>Hugo -- gohugo.io</generator><language>en</language><atom:link href="/docs/tempo/v2.9.x/set-up-for-tracing/instrument-send/set-up-collector/tail-sampling/index.xml" rel="self" type="application/rss+xml"/><item><title>Add tail sampling policies and strategies</title><link>https://grafana.com/docs/tempo/v2.9.x/set-up-for-tracing/instrument-send/set-up-collector/tail-sampling/policies-strategies/</link><pubDate>Tue, 07 Apr 2026 10:28:26 +0000</pubDate><guid>https://grafana.com/docs/tempo/v2.9.x/set-up-for-tracing/instrument-send/set-up-collector/tail-sampling/policies-strategies/</guid><content><![CDATA[&lt;h1 id=&#34;tail-sampling-policies-and-strategies&#34;&gt;Tail sampling policies and strategies&lt;/h1&gt;
&lt;p&gt;
    &lt;a href=&#34;/docs/tempo/v2.9.x/configuration/grafana-alloy/tail-sampling/&#34;&gt;Tail sampling strategies&lt;/a&gt; consider all, or a subset, of the spans that have been collected by an OpenTelemetry Collector &lt;a href=&#34;https://opentelemetry.io/docs/concepts/distributions/&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;distribution&lt;/a&gt;, such as &lt;a href=&#34;/docs/alloy/latest/&#34;&gt;Grafana Alloy&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&#34;add-tail-sampling-to-your-telemetry-pipeline&#34;&gt;Add tail sampling to your Telemetry pipeline&lt;/h2&gt;
&lt;p&gt;Tail sampling is currently defined as part of a telemetry pipeline.
Alloy and other collectors are part of the &lt;code&gt;processing&lt;/code&gt; set of components that are executed after telemetry has been received by Alloy, but before it is exported to a trace storage system such as to Grafana Tempo or Grafana Cloud Traces.&lt;/p&gt;
&lt;p&gt;In the context of OpenTelemetry, tail sampling is implemented by configuring sampling policies.
A sampling policy provides the criteria that makes a decision to sample or discard a trace.
These criteria might include decisions based on specific response status codes, trace duration, attribute values, or other custom-defined rules.
Tail sampling operates as part of the telemetry processing pipeline in Alloy: it can make informed decisions based on the entire trace as opposed to isolated spans.
The sampling criteria policies are defined within a tail sampling block.
For more information, refer to &lt;a href=&#34;/docs/alloy/latest/reference/components/otelcol/otelcol.processor.tail_sampling/&#34;&gt;tail sampling processor block&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&#34;use-cases&#34;&gt;Use cases&lt;/h3&gt;
&lt;p&gt;Sampling, both head and tail, is commonly used to ensure that only relevant traces are stored for observation.
There are common use cases that are generally applied:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Reduction of stored tracing telemetry volume. Higher volumes of unused trace data can lead to unnecessary costs.&lt;/li&gt;
&lt;li&gt;Dropping the collection of traces that don’t really add any informational value to the overall health of an application. This includes traces that may be generated by the endpoints for health checks, such as liveness or readiness probes in Kubernetes.&lt;/li&gt;
&lt;li&gt;Replicated traces across active-active HA instances.&lt;/li&gt;
&lt;li&gt;Ensuring that only critical issues are sampled (such as erroring traces, or those with above average latencies).&lt;/li&gt;
&lt;li&gt;Sampling a baseline number of traces across all requests (common patterns are 1% or fewer), to ensure that comparisons can be made between nominal and anomalous traces.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;example-configuration&#34;&gt;Example configuration&lt;/h3&gt;
&lt;p&gt;For example, this basic Alloy configuration receives OTLP data either via HTTP or gRPC and passes incoming trace spans into the tail sampling processor.
Before sending the trace spans to a tracing store like Tempo, the tail sampling processor decides whether or not to sample the trace based on the probabilistic policy.
The probabilistic policy samples a specified percentage of traces observed randomly.&lt;/p&gt;
&lt;p&gt;Defaults are used for the tail sampling processor.&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;Alloy&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-alloy&#34;&gt;// Expose receiving OTLP data
otelcol.receiver.otlp &amp;#34;example&amp;#34; {
  // Allow OTLP HTTP data on all interfaces on port 4318
  http {
    endpoint = &amp;#34;0.0.0.0:4318&amp;#34;
  }
  // Allow OTLP gRPC data on all interfaces on port 4317
  grpc {
    endpoint = &amp;#34;0.0.0.0:4317&amp;#34;
  }

  // Send all received trace spans to the tail sampling processor
  output {
    traces = [ otelcol.processor.tail_sampling.example.input ]
  }
}

// Make decisions on whether to sample or discard traces
otelcol.processor.tail_sampling &amp;#34;example&amp;#34; {
  // Define a single probabilistic processor to determine sampling
  policy {
    // The name of the policy, each policy name must be unique for this tail sampling instance
    name = &amp;#34;example_probabilistic&amp;#34;
    // The policy type is probabilistic
    type = &amp;#34;probabilistic&amp;#34;

    // Each policy type is defined by a block for the policy with specific parameters for it
    probabilistic {
      // The overall ratio of traces that have been received to randomly sample.
      // In this case 1 in 10.
      sampling_percentage = 10
    }
  }

  // Output all sampled trace spans to the OTLP exporter.
  output {
    traces = [ otelcol.exporter.otlp.example.input ]
  }
}

// The OTLP exporter sends telemetry onwards to a downstream destination.
otelcol.exporter.otlp &amp;#34;example&amp;#34; {
  // The client block defines the target destination.
  client {
    // The endpoint denotes the location of the host receiving the sampled trace
    // data. In this case a local Tempo instance.
    endpoint = &amp;#34;http://tempo:4318&amp;#34;
  }
}&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;h2 id=&#34;policy-types&#34;&gt;Policy types&lt;/h2&gt;
&lt;p&gt;The table lists available policy types for the tail sampling processor.
For additional information, refer to the &lt;a href=&#34;/docs/alloy/latest/reference/components/otelcol/otelcol.processor.tail_sampling/&#34;&gt;&lt;code&gt;otelcol.processor.tail_sampling&lt;/code&gt; component&lt;/a&gt; in the Alloy documentation and the &lt;a href=&#34;https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/processor/tailsamplingprocessor/README.md&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;Tail Sampling Processor README&lt;/a&gt; for the OTel Collector.&lt;/p&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&gt;Policy&lt;/th&gt;
              &lt;th&gt;Description&lt;/th&gt;
              &lt;th&gt;Useful for&lt;/th&gt;
          &lt;/tr&gt;
      &lt;/thead&gt;
      &lt;tbody&gt;
          &lt;tr&gt;
              &lt;td&gt;&lt;a href=&#34;/docs/alloy/latest/reference/components/otelcol/otelcol.processor.tail_sampling/&#34;&gt;always_sample&lt;/a&gt;&lt;/td&gt;
              &lt;td&gt;Samples all traces.&lt;/td&gt;
              &lt;td&gt;Debugging or collecting all data.&lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
              &lt;td&gt;&lt;a href=&#34;/docs/alloy/latest/reference/components/otelcol/otelcol.processor.tail_sampling/#and&#34;&gt;and&lt;/a&gt;&lt;/td&gt;
              &lt;td&gt;Lets you combine multiple policies using a logical &lt;code&gt;AND&lt;/code&gt; operation.&lt;/td&gt;
              &lt;td&gt;Activating one or more policies.&lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
              &lt;td&gt;&lt;a href=&#34;/docs/alloy/latest/reference/components/otelcol/otelcol.processor.tail_sampling/#boolean_attribute&#34;&gt;boolean_attribute&lt;/a&gt;&lt;/td&gt;
              &lt;td&gt;Samples based on a boolean attribute (resource and record).&lt;/td&gt;
              &lt;td&gt;Feature flags or debug modes.&lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
              &lt;td&gt;&lt;a href=&#34;/docs/alloy/latest/reference/components/otelcol/otelcol.processor.tail_sampling/#composite&#34;&gt;composite&lt;/a&gt;&lt;/td&gt;
              &lt;td&gt;Samples based on a combination of samplers, with ordering and rate allocation per sampler.&lt;/td&gt;
              &lt;td&gt;Matching multiple different conditions.&lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
              &lt;td&gt;&lt;a href=&#34;/docs/alloy/latest/reference/components/otelcol/otelcol.processor.tail_sampling/#latency&#34;&gt;latency&lt;/a&gt;&lt;/td&gt;
              &lt;td&gt;Samples traces based on their duration.&lt;/td&gt;
              &lt;td&gt;Identifying slow performance.&lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
              &lt;td&gt;&lt;a href=&#34;/docs/alloy/latest/reference/components/otelcol/otelcol.processor.tail_sampling/#numeric_attribute&#34;&gt;numeric_attribute&lt;/a&gt;&lt;/td&gt;
              &lt;td&gt;Samples based on the number attributes (resource and record).&lt;/td&gt;
              &lt;td&gt;Capturing large responses.&lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
              &lt;td&gt;&lt;a href=&#34;/docs/alloy/latest/reference/components/otelcol/otelcol.processor.tail_sampling/#ottl_condition&#34;&gt;ottl_condition&lt;/a&gt;&lt;/td&gt;
              &lt;td&gt;Samples based on a given boolean OpenTelemetry Transformation Language (OTTL) condition (span and span event).&lt;/td&gt;
              &lt;td&gt;Applying complex and specific filtering.&lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
              &lt;td&gt;&lt;a href=&#34;/docs/alloy/latest/reference/components/otelcol/otelcol.processor.tail_sampling/#probabilistic&#34;&gt;probabilistic&lt;/a&gt;&lt;/td&gt;
              &lt;td&gt;Samples a percentage of traces.&lt;/td&gt;
              &lt;td&gt;Filtering only a percentage of received traces. Reducing data received.&lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
              &lt;td&gt;&lt;a href=&#34;/docs/alloy/latest/reference/components/otelcol/otelcol.processor.tail_sampling/#rate_limiting&#34;&gt;rate_limiting&lt;/a&gt;&lt;/td&gt;
              &lt;td&gt;Samples based on rate of spans per second.&lt;/td&gt;
              &lt;td&gt;Controlling data volume.&lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
              &lt;td&gt;&lt;a href=&#34;/docs/alloy/latest/reference/components/otelcol/otelcol.processor.tail_sampling/#span_count&#34;&gt;span_count&lt;/a&gt;&lt;/td&gt;
              &lt;td&gt;Samples based on the minimum number of spans within the observed trace.&lt;/td&gt;
              &lt;td&gt;Limiting sampled data to a specific number of spans within a trace.&lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
              &lt;td&gt;&lt;a href=&#34;/docs/alloy/latest/reference/components/otelcol/otelcol.processor.tail_sampling/#status_code&#34;&gt;status_code&lt;/a&gt;&lt;/td&gt;
              &lt;td&gt;Samples based upon the status code, either OK, Error, or Unset.&lt;/td&gt;
              &lt;td&gt;Capturing erroring traces.&lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
              &lt;td&gt;&lt;a href=&#34;/docs/alloy/latest/reference/components/otelcol/otelcol.processor.tail_sampling/#string_attribute&#34;&gt;string_attribute&lt;/a&gt;&lt;/td&gt;
              &lt;td&gt;Samples based on string attributes (resource and record) value matches.&lt;/td&gt;
              &lt;td&gt;Filtering specific services or database queries.&lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
              &lt;td&gt;&lt;a href=&#34;/docs/alloy/latest/reference/components/otelcol/otelcol.processor.tail_sampling/#trace_state&#34;&gt;trace_state&lt;/a&gt;&lt;/td&gt;
              &lt;td&gt;Samples based on TraceState value matches.&lt;/td&gt;
              &lt;td&gt;Implementing complex sampling strategies that rely on trace context.&lt;/td&gt;
          &lt;/tr&gt;
      &lt;/tbody&gt;
    &lt;/table&gt;
  &lt;/div&gt;
&lt;/section&gt;&lt;h3 id=&#34;policy-order&#34;&gt;Policy order&lt;/h3&gt;
&lt;p&gt;Policies are evaluated in the order they&amp;rsquo;re defined.
When you define your policies, make sure you consider the order in which they&amp;rsquo;re evaluated.
The following points are important to consider:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Policies are processed sequentially in the order they are defined in the configuration&lt;/li&gt;
&lt;li&gt;Once any policy condition is satisfied, evaluation stops - remaining policies are not checked&lt;/li&gt;
&lt;li&gt;This creates a &amp;ldquo;first-match wins&amp;rdquo;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Being aware of the policy order ensures that your most important observability signals, such as RED (rate, error, duration) metrics, aren&amp;rsquo;t accidentally filtered out by broader sampling rules.&lt;/p&gt;
&lt;p&gt;For example, add &lt;code&gt;probabilistic&lt;/code&gt; policies last since they act as a catch-all after all other policies have been evaluated.
If you have three policies in place, &lt;code&gt;status_code&lt;/code&gt;, &lt;code&gt;latency&lt;/code&gt;, and &lt;code&gt;probabilistic&lt;/code&gt;, then the &lt;code&gt;probabilistic&lt;/code&gt; policy must be the last policy specified so it doesn&amp;rsquo;t prevent the &lt;code&gt;status_code&lt;/code&gt; and &lt;code&gt;latency&lt;/code&gt; from being evaluated.
If the &lt;code&gt;probabilistic&lt;/code&gt; policy samples at 10% and is evaluated first, then 10% of traces were sampled.
No further evaluation on the other policies happens because one of the tail sampling processor conditions has been satisfied.
Traces with errors and high latency are potentially thrown away.
Specifying the &lt;code&gt;status_code&lt;/code&gt; policy to check for span errors and the &lt;code&gt;latency&lt;/code&gt; policy to check for high latency first catches all potential errors and latency issues before probabilistic sampling occurs.
This ensures that all of the errors and high duration spans are captured.&lt;/p&gt;
&lt;h2 id=&#34;sampling-policies-and-use-cases&#34;&gt;Sampling policies and use cases&lt;/h2&gt;
&lt;p&gt;This section provides examples for the policy strategies.&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;Sample data at the collector after metrics generation so that all traces are available to generate accurate metrics. If you generate metrics from sampled traces, the sampling affects their values.&lt;/p&gt;&lt;/blockquote&gt;&lt;/div&gt;

&lt;h3 id=&#34;always-sample&#34;&gt;Always sample&lt;/h3&gt;
&lt;p&gt;You can use &lt;code&gt;always_sample&lt;/code&gt; when you want to capture all tracing data. This could be useful for troubleshooting.&lt;/p&gt;
&lt;p&gt;Refer to the &lt;a href=&#34;/docs/latest/reference/components/otelcol/otelcol.processor.tail_sampling/&#34;&gt;&lt;code&gt;always_sample&lt;/code&gt; policy documentation&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;Alloy&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-alloy&#34;&gt;policy {
    // The example below is for the `always_sample` policy
    name = &amp;#34;example_always_sample&amp;#34;
    type = &amp;#34;always_sample&amp;#34;
}&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;h3 id=&#34;and&#34;&gt;And&lt;/h3&gt;
&lt;p&gt;You use the &lt;code&gt;and&lt;/code&gt; sampling policy when you want to match on multiple conditions. This example uses a probabilistic sampler and the latency sampling policy.&lt;/p&gt;
&lt;p&gt;You can use this to look for slow requests and sample a percentage of traces.&lt;/p&gt;
&lt;p&gt;Refer to the &lt;a href=&#34;/docs/alloy/latest/reference/components/otelcol/otelcol.processor.tail_sampling/#and&#34;&gt;&lt;code&gt;and&lt;/code&gt; policy documentation&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;Alloy&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-alloy&#34;&gt;policy {
    // The example below is for the `and` sampling policy
    name = &amp;#34;example_and&amp;#34;
    type = &amp;#34;and&amp;#34;
    and {
      policies = [
        name = &amp;#34;example_probabilistic&amp;#34;
        type = &amp;#34;probabilistic&amp;#34;
        probabilistic {
         // The percentage of traces to &amp;#34;randomly&amp;#34; sample.
         sampling_percentage = 15
        },
        name = &amp;#34;example_latency&amp;#34;
        type = &amp;#34;latency&amp;#34;
        latency {
         // The minimum duration for a trace to be sampled
         threshold_ms = 5000
       }
    ]
  }
}&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;h3 id=&#34;boolean-attribute&#34;&gt;Boolean attribute&lt;/h3&gt;
&lt;p&gt;Use &lt;code&gt;boolean_attribute&lt;/code&gt; to sample based on whether a specific span attribute with a boolean value is true or false. Any span with the named span attribute set to the given boolean value will cause the trace to be sampled.&lt;/p&gt;
&lt;p&gt;Refer to the &lt;a href=&#34;/docs/alloy/latest/reference/components/otelcol/otelcol.processor.tail_sampling/#boolean_attribute&#34;&gt;&lt;code&gt;boolean_attribute&lt;/code&gt; policy documentation&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;Alloy&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-alloy&#34;&gt;policy {
    // The example below is for the `boolean_attribute` sampling policy
    name = &amp;#34;example_boolean_attribute&amp;#34;
    type = &amp;#34;boolean_attribute&amp;#34;

    boolean_attribute {
      // The span or resource attribute to be considered.
      key = &amp;#34;my.boolean&amp;#34;
      // Sample the trace if the value is boolean and set to `true`.
      value = true
    }
  }&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;h3 id=&#34;composite&#34;&gt;Composite&lt;/h3&gt;
&lt;p&gt;This policy, similar to &lt;code&gt;and&lt;/code&gt;, is built up of multiple sub-policies.
Unlike &lt;code&gt;and&lt;/code&gt;, &lt;code&gt;composite&lt;/code&gt; specifies a maximum throughput of spans to be sampled each second.
Each sub-policy is given a weighting by percentage of maximum throughput.
Should the percentage be maxed out during evaluation, then the other policies in the given order are evaluated instead.
Because &lt;code&gt;composite&lt;/code&gt; is evaluated just like any other sampling policy, it can be used in conjunction with others to act as final decision maker to limit trace sample output should no other policies match.
Generally, composite policies end with an &lt;code&gt;always_sample&lt;/code&gt; policy type to ensure that traces are still sampled should none of the other aggregated policies inside it match.&lt;/p&gt;
&lt;p&gt;Refer to the &lt;a href=&#34;/docs/alloy/latest/reference/components/otelcol/otelcol.processor.tail_sampling/#composite&#34;&gt;&lt;code&gt;composite&lt;/code&gt; policy documentation&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;Alloy&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-alloy&#34;&gt;policy {
    // The example below is for the `composite` sampling policy
    name = &amp;#34;composite-policy&amp;#34;
    type = &amp;#34;composite&amp;#34;
    composite {
            // Limit sampling to a maximum of 500 spans per second.
            max_total_spans_per_second = 500
            // Evaluate the policies in the following order.
            // This acts like the default drop-through policy matcher.
            policy_order = [&amp;#34;composite-policy-keyvalue&amp;#34;, &amp;#34;composite-policy-always&amp;#34;]
            // Sample any trace with a 20x status code.
            composite_sub_policy {
                name = &amp;#34;composite-policy-keyvalue&amp;#34;
                type = &amp;#34;string_attribute&amp;#34;
                string_attribute {
                    key = &amp;#34;http.code&amp;#34;
                    enabled_regex_matching = true
                    values = [ &amp;#34;20[0|1|2]&amp;#34; ]
                }
            }
            // Finalise with an `always_sample` policy type.
            composite_sub_policy {
                name = &amp;#34;composite-policy-always&amp;#34;
                type = &amp;#34;always_sample&amp;#34;
            }
            // Allocate 80% of sampling to the `string_attribute` policy.
            // The remaining 20% is allocated to the `always_sample` policy.
            rate_allocation {
                policy = &amp;#34;composite-policy-keyvalue&amp;#34;
                percent = 80
            }
            rate_allocation {
                policy = &amp;#34;composite-policy-always&amp;#34;
                percent = 20
            }
        }
    }&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;h3 id=&#34;latency&#34;&gt;Latency&lt;/h3&gt;
&lt;p&gt;The &lt;code&gt;latency&lt;/code&gt; policy is used to look for slow-running spans.
For example, you can use it for performance monitoring.
Slow-running spans can indicate performance bottlenecks.
The example samples for traces that are between 3s and 10s long.&lt;/p&gt;
&lt;p&gt;Refer to the &lt;a href=&#34;/docs/alloy/latest/reference/components/otelcol/otelcol.processor.tail_sampling/#latency&#34;&gt;&lt;code&gt;latency&lt;/code&gt; policy documentation&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;Alloy&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-alloy&#34;&gt;policy {
    // The example below is for the `latency` sampling policy
    name = &amp;#34;example_latency&amp;#34;
    type = &amp;#34;latency&amp;#34;

    latency {
      // The minimum duration for a trace to be sampled
      threshold_ms = 3000
      // The maximum duration for a trace to be sampled
      max_duration_ms = 10000
    }
  }&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;h3 id=&#34;numeric-attribute&#34;&gt;Numeric attribute&lt;/h3&gt;
&lt;p&gt;The &lt;code&gt;numeric_attribute&lt;/code&gt; policy lets you sample based on a number of attributes.
In this example below, spans are sampled where &lt;code&gt;http.response_content_length&lt;/code&gt; is between 10,000 and 500,000.
The sample span below would be captured because the attribute value falls within the specified range.&lt;/p&gt;
&lt;p&gt;Refer to the &lt;a href=&#34;/docs/alloy/latest/reference/components/otelcol/otelcol.processor.tail_sampling/#numeric_attribute&#34;&gt;&lt;code&gt;numeric_attribute&lt;/code&gt; policy documentation&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;Alloy&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-alloy&#34;&gt;policy {
    // The example below is for the `numeric_attribute` sampling policy
    name = &amp;#34;example_numeric_attribute&amp;#34;
    type = &amp;#34;numeric_attribute&amp;#34;

    numeric_attribute {
      // The span or resource attribute to be considered.
      key = &amp;#34;http.response_content_length&amp;#34;
      // The minimum value for the attribute to be sampled.
      min_value = 10000
      // The maximum value for the attribute to be sampled.
      max_value = 500000
    }
  }&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;h3 id=&#34;ottl-condition&#34;&gt;OTTL condition&lt;/h3&gt;
&lt;p&gt;This policy type lets you configure policies based around the OpenTelemetry Transformation Language (OTTL).
The various language semantics let you write flexible and detailed sampling policies that can evaluate any trace span conditions to determine whether or not to sample a trace.
If OTTL conditions are particularly complex, this flexibility can potentially create resource overhead.&lt;/p&gt;
&lt;p&gt;Refer to the &lt;a href=&#34;/docs/alloy/latest/reference/components/otelcol/otelcol.processor.tail_sampling/#ottl_condition&#34;&gt;&lt;code&gt;ottl_condition&lt;/code&gt; policy documentation&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;Alloy&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-alloy&#34;&gt;policy {
    // The example below is for the `ottl_condition` sampling policy
    name = &amp;#34;example_ottl_condition&amp;#34;
    type = &amp;#34;ottl_condition&amp;#34;

    ottl_condition {
        condition = &amp;#34;resource.attribute[&amp;#39;service.name&amp;#39;] == &amp;#39;checkout_service&amp;#39;&amp;#34;
    }
  }&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;h3 id=&#34;probabilistic&#34;&gt;Probabilistic&lt;/h3&gt;
&lt;p&gt;Probabilistic sampling lets you determine a ratio of traces that should be sampled.
This is within a range of &lt;code&gt;0&lt;/code&gt; to &lt;code&gt;100%&lt;/code&gt;, and selects the required percentage of traces from those it receives based on the number of traces per second configured.
This can be combined with varying hashing salt values, should multiple collectors be carrying out sampling simultaneously, for example, in a load balanced sampling hierarchy).&lt;/p&gt;
&lt;p&gt;Refer to the &lt;a href=&#34;/docs/alloy/latest/reference/components/otelcol/otelcol.processor.tail_sampling/#probabilistic&#34;&gt;&lt;code&gt;probabilistic&lt;/code&gt; policy documentation&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;Alloy&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-alloy&#34;&gt;policy {
    // The example below is for the `probabilistic` sampling policy
    name = &amp;#34;example_probabilistic&amp;#34;
    type = &amp;#34;probabilistic&amp;#34;

    probabilistic {
	// The percentage of traces to &amp;#34;randomly&amp;#34; sample.
      sampling_percentage = 10
    }
  }&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;h3 id=&#34;rate-limiting&#34;&gt;Rate limiting&lt;/h3&gt;
&lt;p&gt;This policy type samples traces based around the configured spans per second.
This ensures that only traces that conform to the number of those spans available in that trace are sampled, any trace with greater than this number of spans will automatically be dropped.&lt;/p&gt;
&lt;p&gt;Refer to the &lt;a href=&#34;/docs/alloy/latest/reference/components/otelcol/otelcol.processor.tail_sampling/#rate_limiting%60&#34;&gt;&lt;code&gt;rate_limiting&lt;/code&gt; policy documentation&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;Alloy&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-alloy&#34;&gt;policy {
    // The example below is for the `rate_limiting` sampling policy
    name = &amp;#34;example_rate_limiting&amp;#34;
    type = &amp;#34;rate_limiting&amp;#34;

    rate_limiting {
       // Defines the maximum number of collective spans in a second that the trace should have for it to be sampled.
	spans_per_second = 20
    }
  }&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;h3 id=&#34;span-count&#34;&gt;Span count&lt;/h3&gt;
&lt;p&gt;The &lt;code&gt;span_count&lt;/code&gt; policy accepts a window of minimum and maximum number of spans for a trace to be sampled once the decision period is reached.&lt;/p&gt;
&lt;p&gt;Setting the minimum number of spans to zero essentially replicates the rate limiting policy.&lt;/p&gt;
&lt;p&gt;Refer to the &lt;a href=&#34;/docs/alloy/latest/reference/components/otelcol/otelcol.processor.tail_sampling/#span_count&#34;&gt;&lt;code&gt;span_count&lt;/code&gt; policy documentation&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;Alloy&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-alloy&#34;&gt;policy {
    // The example below is for the `span_count` sampling policy
    name = &amp;#34;example_span_count&amp;#34;
    type = &amp;#34;span_count&amp;#34;

    span_count {
	min_spans = 5
	max_spans = 50
    }
  }&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;h3 id=&#34;status-code&#34;&gt;Status code&lt;/h3&gt;
&lt;p&gt;The &lt;code&gt;status_code&lt;/code&gt; policy check for the span intrinsic status of &lt;code&gt;OK&lt;/code&gt;, &lt;code&gt;UNSET&lt;/code&gt;, or &lt;code&gt;ERROR&lt;/code&gt;.
The policy takes an array of statuses, so only traces with at least one span that matches these statuses are sampled.&lt;/p&gt;
&lt;p&gt;Refer to the &lt;a href=&#34;/docs/alloy/latest/reference/components/otelcol/otelcol.processor.tail_sampling/#status_code&#34;&gt;&lt;code&gt;status_code&lt;/code&gt; policy documentation&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;Alloy&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-alloy&#34;&gt;policy {
    // The example below is for the `status_code` sampling policy
    name = &amp;#34;example_status_code&amp;#34;
    type = &amp;#34;status_code&amp;#34;

    status_code {
      // An array of status codes; should any of the spans in a trace match one
      // of the status codes, it will be sampled.
      status_codes = [&amp;#34;ERROR&amp;#34;]
    }
  }&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;h3 id=&#34;string-attribute&#34;&gt;String attribute&lt;/h3&gt;
&lt;p&gt;This policy examines the values of a specified string attribute key for trace’s spans, to make a sampling decision.
There are a number of configurable options, including the ability to use regular expressions, inversion matching, for example, to only sample traces that don&amp;rsquo;t match a regular expression, and an LRU cache for accelerating future policy decision making.&lt;/p&gt;
&lt;p&gt;Refer to the &lt;a href=&#34;/docs/alloy/latest/reference/components/otelcol/otelcol.processor.tail_sampling/#string_attribute&#34;&gt;&lt;code&gt;string_attribute&lt;/code&gt; policy documentation&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;Alloy&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-alloy&#34;&gt;policy {
    // The example below is for the `string_attribute` sampling policy
    name = &amp;#34;example_string_attribute&amp;#34;
    type = &amp;#34;string_attribute&amp;#34;

    string_attribute {
      // The span or resource attribute to be considered.
      key = &amp;#34;db.statement&amp;#34;
      // Enables regular expression matching to be defined in the attribute values defined in `values`. Defaults to false for exact pattern matching.
      enabled_regex_matching = true
      // The number of LRU cache entries to save, to allow less full regexps to be run during decision making.
      cache_max_size = 100
      // Determines if a value match should determine whether the trace is sampled. `false` to only sample traces when the attribute&amp;#39;s value matches, `true` to only sample traces where the attribute&amp;#39;s value does not match.
      invert_match = false
      values = [&amp;#34;SELECT.*&amp;#34;, &amp;#34;INSERT.*&amp;#34;]
    }
  }&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;h3 id=&#34;trace-state&#34;&gt;Trace state&lt;/h3&gt;
&lt;p&gt;The &lt;code&gt;trace_state&lt;/code&gt; policy looks at the traces states associated with the incoming spans for traces and then compares the keys, should any exist, with those configured by the policy. This ensures that only traces with the relevant trace state keys are sampled.&lt;/p&gt;
&lt;p&gt;Refer to the &lt;a href=&#34;/docs/alloy/latest/reference/components/otelcol/otelcol.processor.tail_sampling/#trace_state&#34;&gt;&lt;code&gt;trace_state&lt;/code&gt; policy documentation&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;Alloy&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-alloy&#34;&gt;policy {
    // The example below is for the `trace_state` sampling policy
    name = &amp;#34;example_trace_state&amp;#34;
    type = &amp;#34;trace_state&amp;#34;

    trace_state {
	key = &amp;#34;sampling.priority&amp;#34;
	values = [&amp;#34;1&amp;#34;]
    }
  }&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;h2 id=&#34;real-world-configuration-example&#34;&gt;Real-world configuration example&lt;/h2&gt;
&lt;p&gt;The following is a detailed example of a configuration that might be applied to an application with a small set of services.&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;Alloy&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-alloy&#34;&gt;// Tail sampling processor is taken from the upstream OpenTelemetry Collector repository, which can be found in
// GitHub here: https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/processor/tailsamplingprocessor/README.md

otelcol.processor.tail_sampling &amp;#34;multipolicy&amp;#34; {
    // Total wait time from the start of a trace before making a sampling decision. Note that smaller time
    // periods can potentially cause a decision to be made before the end of a trace has occurred.
    decision_wait = &amp;#34;30s&amp;#34;
    // The following policies follow a logical OR pattern, meaning that if any of the policies match,
    // the trace will be sampled and the remaining policies will not be evaluated. This creates a drop-through
    // mechanism.
    // Always sample on an error regardless of any other conditions.
    policy {
        // The name of the policy can be used for logging purposes.
        name = &amp;#34;sample-erroring-traces&amp;#34;
        // The type must match the type of policy to be used, in this case examining the status code
        // of every span in the trace.
        type = &amp;#34;status_code&amp;#34;
        // This block determines the error codes that should match in order to keep the trace,
        // in this case the OpenTelemetry &amp;#39;ERROR&amp;#39; code.
        status_code {
            status_codes = [ &amp;#34;ERROR&amp;#34; ]
        }
    }

    // `and` policies allow for multiple conditions to hold true for a trace to be sampled. This is extremely useful
    // for using the same types of sub-policies, with re-used keys/latencies/etc. to create a more complex sampling
    // policy.
    // `and` policies follow the same drop-through mechanism as `or` policies, where if any sub-policy fails, the
    // trace is not sampled and the remaining sub-policies are not evaluated.
    // This policy will sample traces where the total latency is over 5s and the service name matches a regex and
    // at a 10% probabilistic rate.
    policy {
        // The name of the policy can be used for logging purposes.
        name = &amp;#34;5s-api-policy&amp;#34;
        // The type must match the type of policy to be used, in this case the total latency of the trace.
        type = &amp;#34;and&amp;#34;
        and {
            // This block is true for any trace that is over 5s in total length.
            and_sub_policy {
                name = &amp;#34;5s-api-policy-latency&amp;#34;
                type = &amp;#34;latency&amp;#34;
                // Latency for entire trace in milliseconds. The duration looks for the earliest and start time
                // and latest end time for all the span in a given trace.
                latency {
                    threshold_ms = 5000
                }
            }

            // This sub-policy is evaluated true if the service names match the given regex[s].
            and_sub_policy {
                name = &amp;#34;5s-api-policy-service&amp;#34;
                type = &amp;#34;string_attribute&amp;#34;
                string_attribute {
                    // Attribute to match against, in this case the service name.
                    key = &amp;#34;service.name&amp;#34;
                    // String tested is a regex, not a literal string.
                    enabled_regex_matching = true
                    // Values to match against the key (note this uses two regex values as an example, it would be more
                    // efficient to evaluate a single regex that matches both values such as
                    // `(?:alternative-)*api-service-.&amp;#43;)`.
                    values = [ &amp;#34;api-service-.&amp;#43;&amp;#34;, &amp;#34;alternative-api-service-.&amp;#43;&amp;#34; ]
                }
            }


            // Probabilistic sampling is a way to sample a percentage of traces based on a given rate.
            // This sub-policy is evaluated true if the trace is sampled at a 10% rate.
            // Note that the `rate_limiting` policy also exist, which is a good alternative to probabilistic sampling when
            // you always want to sample based around a fixed rate of spans per second.
            and_sub_policy {
                name = &amp;#34;5s-api-policy-rate&amp;#34;
                type = &amp;#34;probabilistic&amp;#34;
                probabilistic {
                    // The rate to sample at, in this case 10%.
                    sampling_percentage = 10
                }
            }
        }
    }

    // `composite` policies, similar to `and` policies, are built up of multiple sub-policies. However, unlike `and`
    // policies, `composite` policies specify a maximum throughput of spans to be sampled each second. Each sub-policy
    // is given a weighting by percentage of maximum throughput. Should the percentage be maxed out during evaluation,
    // then the other policies in the given order are evaluated instead. Because this policy is evaluated as any other
    // policy, it can be used in conjunction with other policies to act as final assessment to limit trace sample output
    // should no other policies match.
    policy {
        name = &amp;#34;composite-policy&amp;#34;
        type = &amp;#34;composite&amp;#34;
        composite {
            // Limit sampling to a maximum of 5000 spans per second.
            max_total_spans_per_second = 5000
            // Evaluate the policies in the following order. This again acts like the default drop-through policy matcher,
            // but also evaluates on the percentage of rate allocation assigned to each policy (see `rate_allocation`
            // blocks below).
            policy_order = [&amp;#34;composite-policy-keyvalue&amp;#34;, &amp;#34;composite-policy-latency&amp;#34;, &amp;#34;composite-policy-always&amp;#34;]

            // Sample any trace with a 20x status code.
            composite_sub_policy {
                name = &amp;#34;composite-policy-keyvalue&amp;#34;
                type = &amp;#34;string_attribute&amp;#34;
                string_attribute {
                    key = &amp;#34;http.code&amp;#34;
                    enabled_regex_matching = true
                    values = [ &amp;#34;20[0|1|2]&amp;#34; ]
                }
            }
            // Latency policy for any trace over 2s.
            composite_sub_policy {
                name = &amp;#34;composite-policy-latency&amp;#34;
                type = &amp;#34;latency&amp;#34;
                latency {
                    threshold_ms = 2000
                }
            }

            // When using the `composite` policy type, it&amp;#39;s generally best practice to finalise with a policy that&amp;#39;ll still
            // let the remainder of the traces through (or at least a subset of them). For this reason, an `always_sample`
            // policy is a good choice (or an extra `probabilistic` policy with appropriate percentage of spans available
            // to the `composite` policy at final evaluation).
            composite_sub_policy {
                name = &amp;#34;composite-policy-always&amp;#34;
                type = &amp;#34;always_sample&amp;#34;
            }

            // Allocate 45% of the 5000 spans per second to the `keyvalue` policy and 45% to the `latency` policy.
            // The remaining 10% is allocated to the `always_sample` policy.
            rate_allocation {
                policy = &amp;#34;composite-policy-keyvalue&amp;#34;
                percent = 45
            }
            rate_allocation {
                policy = &amp;#34;composite-policy-latency&amp;#34;
                percent = 45
            }
            rate_allocation {
                policy = &amp;#34;composite-policy-always&amp;#34;
                percent = 10
            }
        }
    }

    // The output block forwards the kept traces onto the batch processor, which will marshall them
    // for exporting to Tempo.
    output {
        traces = [otelcol.processor.batch.default.input]
    }
}&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
]]></content><description>&lt;h1 id="tail-sampling-policies-and-strategies">Tail sampling policies and strategies&lt;/h1>
&lt;p>
&lt;a href="/docs/tempo/v2.9.x/configuration/grafana-alloy/tail-sampling/">Tail sampling strategies&lt;/a> consider all, or a subset, of the spans that have been collected by an OpenTelemetry Collector &lt;a href="https://opentelemetry.io/docs/concepts/distributions/" target="_blank" rel="noopener noreferrer">distribution&lt;/a>, such as &lt;a href="/docs/alloy/latest/">Grafana Alloy&lt;/a>.&lt;/p></description></item></channel></rss>