> ## Documentation Index
> Fetch the complete documentation index at: https://notes.kodekloud.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Sampling Strategies

> Explains tracing sampling strategies across SDK and Collector, comparing SDK, head, and tail sampling and when to use transforms and sampling processors.

In this lesson we’ll compare sampling points and strategies across the OpenTelemetry stack: starting inside the application (SDK) and moving outward to the Collector. Each diagram is preserved in order and annotated so the flow and decision points are clear.

The OpenTelemetry SDK runs inside your application and is the first—most immediate—place to make sampling decisions for spans and traces.

<Frame>
  <img src="https://mintcdn.com/kodekloud-c4ac6d9a/ej4v9LnsFuza8uyJ/images/Prep-Course-OpenTelemetry-Certified-Associate-OTCA-Certification/Transforming-Telemetry-Pipeline-Processing/Sampling-Strategies/otel-sdk-tracing-diagram-samplers.jpg?fit=max&auto=format&n=ej4v9LnsFuza8uyJ&q=85&s=df7effa2480370f363f39d247acb706a" alt="The image is a diagram illustrating tracing in an application using an OTel SDK, noting &#x22;Tracing Begins: SDK Samplers at the Source.&#x22;" width="1920" height="1080" data-path="images/Prep-Course-OpenTelemetry-Certified-Associate-OTCA-Certification/Transforming-Telemetry-Pipeline-Processing/Sampling-Strategies/otel-sdk-tracing-diagram-samplers.jpg" />
</Frame>

Why sample at the SDK?

* Lowers network and backend load by discarding unneeded spans early.
* Enables consistent per-process sampling configured without code changes.
* Limited by the local view: SDK sampling decisions occur at span creation time and cannot use eventual trace outcomes.

Below is a more focused view showing the SDK and the SDK Sampler component inside an application process.

<Frame>
  <img src="https://mintcdn.com/kodekloud-c4ac6d9a/ej4v9LnsFuza8uyJ/images/Prep-Course-OpenTelemetry-Certified-Associate-OTCA-Certification/Transforming-Telemetry-Pipeline-Processing/Sampling-Strategies/sdk-sampler-reintroduction-diagram.jpg?fit=max&auto=format&n=ej4v9LnsFuza8uyJ&q=85&s=64e4557d29443f85a5701d0a254aa540" alt="The image is a diagram illustrating the reintroduction of the SDK Sampler in an app, featuring an &#x22;Application&#x22; box with &#x22;OTel SDK&#x22; and &#x22;SDK Sampler&#x22; highlighted." width="1920" height="1080" data-path="images/Prep-Course-OpenTelemetry-Certified-Associate-OTCA-Certification/Transforming-Telemetry-Pipeline-Processing/Sampling-Strategies/sdk-sampler-reintroduction-diagram.jpg" />
</Frame>

Common SDK sampler types and when to use them:

| Sampler                      | What it does                                                      | Use case                                      |
| ---------------------------- | ----------------------------------------------------------------- | --------------------------------------------- |
| AlwaysOn                     | Records all traces                                                | Debugging, development, short-lived tests     |
| AlwaysOff                    | Records no traces                                                 | Disable telemetry in specific runs            |
| TraceIdRatio (probabilistic) | Records a fixed percentage of traces using a hash of the trace ID | Control volume with predictable sampling rate |
| ParentBased                  | Follows the parent span's decision                                | Preserve trace consistency across services    |

<Frame>
  <img src="https://mintcdn.com/kodekloud-c4ac6d9a/ej4v9LnsFuza8uyJ/images/Prep-Course-OpenTelemetry-Certified-Associate-OTCA-Certification/Transforming-Telemetry-Pipeline-Processing/Sampling-Strategies/sdk-sampler-diagram-otel-sdk.jpg?fit=max&auto=format&n=ej4v9LnsFuza8uyJ&q=85&s=98b371334888f87f724619282b641fd4" alt="The image shows a diagram of an &#x22;SDK Sampler&#x22; with different types: AlwaysOn, AlwaysOff, TraceIdRatio, and ParentBased. It is part of an application using the OTel SDK." width="1920" height="1080" data-path="images/Prep-Course-OpenTelemetry-Certified-Associate-OTCA-Certification/Transforming-Telemetry-Pipeline-Processing/Sampling-Strategies/sdk-sampler-diagram-otel-sdk.jpg" />
</Frame>

Example: configure SDK sampling via environment variables (spec follows the OpenTelemetry specification and is cross-language):

```bash theme={null}
# Example (cross-language env vars per spec)
export OTEL_TRACES_SAMPLER=parentbased_traceidratio
export OTEL_TRACES_SAMPLER_ARG=0.10  # sample 10% of traces at the SDK (when parent decision allows)
```

<Callout icon="lightbulb" color="#1CB2FE">
  Sampling at the SDK reduces network and backend load, but it discards data early. If you need sampling decisions based on full-trace results (errors, latency spikes, or aggregated attributes), consider sampling later in the pipeline (the Collector).
</Callout>

If the SDK does not sample, or if you need enrichment/normalization before deciding, the OpenTelemetry Collector is a powerful place to apply sampling. The Collector can receive telemetry from many SDKs, augment traces with transforms, and make more informed sampling decisions.

<Frame>
  <img src="https://mintcdn.com/kodekloud-c4ac6d9a/ej4v9LnsFuza8uyJ/images/Prep-Course-OpenTelemetry-Certified-Associate-OTCA-Certification/Transforming-Telemetry-Pipeline-Processing/Sampling-Strategies/data-flow-sdk-collector-diagram.jpg?fit=max&auto=format&n=ej4v9LnsFuza8uyJ&q=85&s=6ecb508016008c51d7ea3b4aadd6fe09" alt="The image is a diagram illustrating a data flow process titled &#x22;From SDK to Collector – Why Sample Again, Where OTTL Helps,&#x22; featuring components such as Receiver, OTTL Transform, and Sampling Processor with Head and Tail Samplers." width="1920" height="1080" data-path="images/Prep-Course-OpenTelemetry-Certified-Associate-OTCA-Certification/Transforming-Telemetry-Pipeline-Processing/Sampling-Strategies/data-flow-sdk-collector-diagram.jpg" />
</Frame>

Transforms in the Collector (using OTTL) let you enrich telemetry so sampling policies can use attributes like error flags, tenant IDs, or latency labels. Example: set an error flag and copy a tenant attribute into spans before sampling.

```yaml theme={null}
processors:
  transform/normalize:
    error_mode: ignore
    traces:
      statements:
        - set(span.attributes["error.flag"], span.status.code == "STATUS_CODE_ERROR")
        - set(span.attributes["tenant"], resource.attributes["tenant"]) where
          resource.attributes["tenant"] != nil
```

After transforms, telemetry flows through processors that can include sampling processors before export.

Two fundamental Collector sampling approaches:

<Frame>
  <img src="https://mintcdn.com/kodekloud-c4ac6d9a/ej4v9LnsFuza8uyJ/images/Prep-Course-OpenTelemetry-Certified-Associate-OTCA-Certification/Transforming-Telemetry-Pipeline-Processing/Sampling-Strategies/head-vs-tail-sampling-collector-diagram.jpg?fit=max&auto=format&n=ej4v9LnsFuza8uyJ&q=85&s=b83277f3b036736d898522e4a39b76f9" alt="The image illustrates a process involving &#x22;Head vs Tail Sampling in the Collector,&#x22; featuring a &#x22;Processor (Sampling)&#x22; leading to &#x22;Head Sampling&#x22; and &#x22;Tail Sampling&#x22; options, with descriptions of each method." width="1920" height="1080" data-path="images/Prep-Course-OpenTelemetry-Certified-Associate-OTCA-Certification/Transforming-Telemetry-Pipeline-Processing/Sampling-Strategies/head-vs-tail-sampling-collector-diagram.jpg" />
</Frame>

Table: Collector sampling comparison

| Approach      | How it works                                                                                                              | Pros                                                                                                  | Cons                                                                       |
| ------------- | ------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------- |
| Head sampling | Decide as spans arrive at the Collector (per-span or per-trace probabilistic policies based on partial info)              | Low memory & CPU, fast, scalable                                                                      | Cannot use full-trace outcomes (may miss important traces)                 |
| Tail sampling | Buffer and assemble a trace (or wait for a decision signal) and then evaluate the entire trace before keeping or dropping | Outcome-aware (keep traces with errors/latency/patterns), more accurate retention of important traces | Requires buffering, more memory and CPU, complexity in distributed systems |

<Callout icon="warning" color="#FF6B6B">
  Tail sampling improves retention of high-value traces but increases memory and processing needs in the Collector. Plan capacity, timeouts, and resource limits carefully to avoid buffering overload.
</Callout>

When to choose which:

* Use SDK or Collector head sampling for lightweight, probabilistic reduction when you only need volume control.
* Use Collector tail sampling when you must make outcome-based decisions (for example, retain all traces that contain errors or unusually high latency).
* Combine approaches: use SDK sampling to reduce baseline volume and tail sampling in the Collector for application-level exceptions or multi-service error patterns.

References and further reading

* OpenTelemetry: [https://opentelemetry.io/](https://opentelemetry.io/)
* OpenTelemetry Collector: [https://opentelemetry.io/docs/collector/](https://opentelemetry.io/docs/collector/)
* OTTL (OpenTelemetry Transformation Language) docs: [https://opentelemetry.io/docs/collector/processing/transform/](https://opentelemetry.io/docs/collector/processing/transform/)

<CardGroup>
  <Card title="Watch Video" icon="video" cta="Learn more" href="https://learn.kodekloud.com/user/courses/prep-course-opentelemetry-certified-associate-certification-otca/module/85787c66-c021-47d9-bd3d-db54bc002465/lesson/5222f050-3143-492f-afd6-56c62ef81fba" />
</CardGroup>
