Adaptive trace sampling with the OpenTelemetry Collector: taming telemetry volume without losing signal

Observability pipelines can sound like playlists for cloud infrastructure — everything playing at once creates a messy mix. Traces are the lead guitar: they reveal structure and timing, but at scale they can overwhelm storage, dashboards, and budgets. A recent addition to the OpenTelemetry Collector ecosystem gives pipeline builders a new control: a dynamic sampling processor that adapts sample rates in real time and records the effective rate in the trace context so metrics and downstream systems can weight sampled traces correctly. (github.com)

This article explains what the dynamic sampling processor does, how it fits into collector-based pipelines, and the trade-offs to keep in mind — with concrete config and behavioral details so the idea stays practical, not academic.

Why adaptive sampling matters (quick recap)

Adaptive sampling sits between those approaches: it observes the traffic, applies rules, and assigns sampling rates that can change per-key (for example per service name, route, or HTTP method) so that frequently noisy keys are sampled at a lower rate while important low-volume keys can retain higher fidelity.

What the new dynamic sampling processor does

A compact config example Below is an illustrative collector YAML snippet that shows the form of rules and samplers (semantic only — small edits may be needed for a production config):

processors: dynamic_sampling: trace_timeout: 30s decision_delay: 2s num_traces: 50000 decision_cache: sampled_cache_size: 10000 non_sampled_cache_size: 10000 rules: - name: keep-errors conditions: - ‘status.code == 2’ sampler: type: always_sample - name: payment-service conditions: - ‘resource.attributes[“service.name”] == “payment”’ sampler: type: ema_dynamic ema_dynamic: goal_sampling_percentage: 5 key_fields: [“http.method”, “http.route”] adjustment_interval: 15s weight: 0.5 - name: default sampler: type: ema_dynamic ema_dynamic: goal_sampling_percentage: 20 key_fields: [“service.name”, “http.status_code”]

This example demonstrates:

Why encoding the sample rate into TraceState matters Recording the effective sampling probability in the W3C TraceState (the ot=th key defined by OpenTelemetry) is the crucial piece that turns sampling from a destructive filter into a statistically-correctable transformation. Systems that convert traces to metrics or compute service-level rates can use the encoded threshold to extrapolate counts and produce accurate, unbiased aggregates despite sampling. The OpenTelemetry spec defines how a rejection threshold is encoded and how to derive adjusted counts from it, enabling consistent sampling and correct downstream weighting. (opentelemetry.io)

How this compares to other sampling processors

Operational trade-offs and tuning knobs

A realistic analogy Think of the pipeline as a live concert sound engineer. The dynamic sampler is not muting the guitar entirely; it’s turning down sections of the mix that are playing at full tilt (very noisy routes) while ensuring the solo still cuts through when the band hits a critical note (an error or a rare route). The ot=th entry is like a label on each recorded take that tells the mixing desk how loud it actually was on stage — so later, when you master the recording into metrics, you can normalize levels properly.

Limitations and sharp edges

Why this matters for pipeline design

Concluding note (no call to action) The dynamic sampling processor is an example of pipeline intelligence — moving early decision-making into the collector so telemetry becomes a controlled, instrumented flow rather than an all-or-nothing flood. Its approach — rule-driven routing to samplers, deterministic decisions, and TraceState-based encoding — addresses the practical tension between observability signal and cost in large-scale systems. For teams managing high-volume tracing, this is a valuable capability to understand and evaluate alongside existing sampling strategies. (pkg.go.dev)