Skip to main content
Sampling is a mechanism to control the noise and overhead introduced by OpenTelemetry by reducing the number of traces collected and sent to the backend.

Understanding Sampling

From opentelemetry-sdk/src/trace/sampler.rs:40-81, sampling can be implemented at different stages:
  • Head sampling - Decision made when creating the span (what OpenTelemetry SDK provides)
  • SDK layer - Implemented in span processors or exporters
  • Out of process - In agents or collectors

Sampling Flags

Two properties control data collection:
  1. is_recording() - If true, the span records events, attributes, and status. Span processors receive all recording spans.
  2. Sampled flag - Set in SpanContext::trace_flags(). Indicates the span will be exported. Only sampled spans reach exporters.
A span can be recording but not sampled (is_recording=true, sampled=false). This allows local metrics without backend export.
The combination is_recording=false and sampled=true is not allowed by the OpenTelemetry API.

Sampling Decisions

From opentelemetry-sdk/src/trace/sampler.rs:22-33:

Sampling Result

Built-in Samplers

OpenTelemetry SDK provides several built-in samplers defined in opentelemetry-sdk/src/trace/sampler.rs:142-167:

AlwaysOn Sampler

Samples every trace:

AlwaysOff Sampler

Never samples any traces:

TraceIdRatioBased Sampler

Samples a percentage of traces based on the trace ID:
TraceIdRatioBased uses the trace ID for sampling decisions, ensuring all spans in a trace have the same sampling decision.

ParentBased Sampler

Respects the parent span’s sampling decision, delegating to another sampler for root spans:
From opentelemetry-sdk/src/trace/sampler.rs:211-236, the ParentBased sampler:
  • If parent is sampled → child is sampled
  • If parent is not sampled → child is not sampled
  • If no parent → delegates to the provided sampler

Environment Variables

Configure sampling via environment variables (from opentelemetry-sdk/src/trace/config.rs:60-100):

Custom Samplers

Implement the ShouldSample trait for custom sampling logic:

Attribute-Based Sampling

Sample based on span attributes:

Rate-Limiting Sampler

Implement rate limiting for high-volume scenarios:

Composite Samplers

Combine multiple sampling strategies:

Jaeger Remote Sampler

With the jaeger_remote_sampler feature, fetch sampling configuration from a remote service:

Best Practices

Always use ParentBased in production to ensure consistent sampling decisions across service boundaries. This prevents partial traces.
Begin with a low sampling rate (e.g., 1-10%) and increase based on traffic volume and backend capacity.
Use custom samplers to always sample critical operations like errors, slow requests, or specific user tiers.
Use RecordOnly decision to collect local metrics without backend export overhead.
Use AlwaysOn in development and testing environments to ensure instrumentation is working correctly.

Complete Example

Next Steps

Span Processors

Configure how sampled spans are processed and exported

Overview

Return to tracing overview