Hay una creencia que destruye presupuestos de observabilidad: “si no recopilo cada traza, podría perder algo importante.”
Es intuitivo. También es incorrecto — o al menos, incorrecto para la mayoría de sistemas que operan a cualquier escala significativa.
La propia documentación de OpenTelemetry lo afirma claramente: si la gran mayoría de tus requests son exitosas y terminan con latencia aceptable y sin errores, no necesitas el 100% de tus trazas para observar de forma significativa tus aplicaciones y sistemas. Solo necesitas el sampling correcto.
Este artículo explica la estadística detrás de esa afirmación, recorre las dos estrategias principales de sampling, y muestra cómo el OpenTelemetry Collector es el componente práctico que hace que todo funcione en producción.
La Estadística de la Representatividad
El sampling no es un compromiso — es un método científico consolidado. El principio central es la representatividad: un grupo más pequeño puede representar con precisión a un grupo más grande, y esto puede verificarse matemáticamente.
La parte contraintuitiva es lo que ocurre a escala. Cuantos más datos generas, menos necesitas para obtener una imagen precisa. Para sistemas de alto volumen, una tasa de sampling del 1% o inferior puede representar con gran precisión el otro 99% de los datos.
Veamos cómo funciona en la práctica. Si tu servicio maneja 10.000 requests por segundo con una latencia p99 de 150ms:
- Sampling al 100%: 10.000 trazas/segundo almacenadas → coste enorme
- Sampling al 1%: 100 trazas/segundo → sigues viendo 100 journeys de requests distintos cada segundo
- Tu cálculo del p99 a partir de esas 100 trazas será estadísticamente indistinguible del calculado con las 10.000
La matemática no miente. El sampling es sólido para el análisis agregado. Lo interesante es qué trazas conservas — y ahí es donde importa la estrategia.
Cuándo el Sampling Tiene Sentido (y Cuándo No)
Antes de entrar en estrategia, conviene ser honesto sobre cuándo el sampling es y no es la decisión correcta.
El sampling vale la pena cuando:
- Generas 1.000 o más trazas por segundo
- La mayoría de tus datos de trazas representa tráfico saludable con poca variación
- Tienes criterios claros de qué datos son “interesantes” (errores, latencia alta, servicios específicos)
- Puedes describir reglas que determinen si los datos deben conservarse o descartarse
- Quieres enrutar los datos descartados a almacenamiento de bajo coste en lugar de eliminarlos del todo
El sampling puede no ser adecuado cuando:
- Generas muy pocos datos (decenas de trazas por segundo o menos)
- Solo usas los datos de observabilidad de forma agregada — puedes pre-agregar en su lugar
- Las normativas prohíben descartar datos completamente
También hay costes reales del sampling que los equipos subestiman:
- Coste de cómputo de ejecutar un proxy de tail-sampling a escala
- Coste de ingeniería de mantener las reglas de sampling conforme evoluciona tu sistema
- Coste de oportunidad de perder datos críticos con técnicas de sampling mal diseñadas
El sampling mal hecho puede ser más caro que no hacerlo. El objetivo es hacerlo bien.
Dos Estrategias: Head Sampling vs. Tail Sampling
OpenTelemetry define dos momentos fundamentalmente distintos en los que puede tomarse una decisión de sampling. Elegir entre ellos — o combinarlos — es la decisión de diseño central.
Head Sampling: Decisiones Rápidas al Principio
El head sampling toma la decisión de conservar/descartar al comienzo mismo de una traza, antes de que se procese ningún span. La forma más común es el Consistent Probability Sampling (también llamado Deterministic Sampling): dado un trace ID y un porcentaje deseado, un hash determinista decide si la traza se conserva.
Request llega → trace ID generado → hash(trace_id) % 100 < 5? → Conservar (5%)
→ Descartar (95%)
Ventajas:
- Simple de entender y configurar
- Extremadamente eficiente — no requiere estado
- Funciona en cualquier punto del pipeline, incluso dentro del propio SDK
- Garantiza trazas completas (sin spans perdidos en las trazas muestreadas)
La limitación crítica:
La decisión se toma antes de saber nada sobre la traza. No puedes usar head sampling por sí solo para garantizar que todas las trazas con errores se conserven, o que las trazas lentas por encima de 500ms se capturen siempre. Estás muestreando a ciegas por probabilidad.
Para muchos sistemas, esto es suficiente. Para sistemas donde los errores y los valores atípicos de latencia son las señales críticas, necesitas la otra estrategia.
Tail Sampling: Decisiones Inteligentes a Posteriori
El tail sampling toma la decisión de sampling después de que todos (o la mayoría de) los spans de una traza están completos. Esto significa que puedes inspeccionar la traza completa antes de decidir si conservarla.
Request completa → todos los spans recopilados → ¿Tiene un error? → Conservar siempre
→ ¿Latencia > 1s? → Conservar siempre
→ En otro caso → Conservar 5%
Ejemplos de lo que permite el tail sampling:
- Conservar siempre trazas con errores — nunca perderte un fallo
- Conservar siempre trazas lentas — detectar regresiones de latencia que de otro modo se muestrearían
- Muestrear más trazas de un nuevo despliegue — mayor escrutinio para nuevos servicios
- Aplicar tasas distintas por servicio — servicios de alto volumen al 0,1%, servicios de bajo volumen al 100%
Esto es dramáticamente más útil para depuración en producción. El trade-off es la complejidad.
Las desventajas del tail sampling:
- Requiere infraestructura con estado. El componente que toma la decisión debe mantener todos los spans de una traza en memoria hasta que la traza esté completa. Para sistemas de alto throughput, esto implica requisitos significativos de memoria.
- Es difícil de operar. El tail sampler puede convertirse en un cuello de botella. Si se queda atrás, puede necesitar recurrir a sampling menos inteligente o empezar a descartar datos.
- A menudo es específico del proveedor. Muchas plataformas de observabilidad comerciales ofrecen tail sampling, pero vinculado a su backend.
Aquí es donde el OpenTelemetry Collector se vuelve indispensable.
El OTel Collector: Donde Vive el Sampling en tu Pipeline
El OpenTelemetry Collector es un proxy vendor-agnostic que se sitúa entre tus servicios instrumentados y tu backend de observabilidad. Recibe datos de telemetría, puede transformarlos y los reenvía a uno o varios destinos.
Para el sampling, es el lugar natural. En lugar de muestrear en cada SDK de forma independiente (lo que fragmenta los datos de tus trazas), el Collector te proporciona un lugar centralizado, configurable y mantenible para implementar tu estrategia de sampling.
[Servicio A] ─┐
[Servicio B] ─┼──► [OTel Collector] ──► lógica de sampling ──► [Backend]
[Servicio C] ─┘
La distribución contrib del Collector incluye dos processors específicamente para esto:
Probabilistic Sampling Processor (Head Sampling)
El probabilisticsamplerprocessor implementa consistent probability sampling. Configura un porcentaje y determinísticamente conserva esa fracción de trazas.
processors:
probabilistic_sampler:
sampling_percentage: 10 # conservar el 10% de todas las trazas
Es la opción más simple y no requiere estado. Ideal cuando quieres reducir el volumen uniformemente sin reglas complejas.
Tail Sampling Processor (Sampling Inteligente)
El tailsamplingprocessor es el potente. Almacena spans en memoria hasta que una traza está completa, luego evalúa un conjunto de políticas configurables para decidir si conservarla o descartarla.
processors:
tail_sampling:
decision_wait: 10s # esperar hasta 10s por todos los spans
num_traces: 100000 # máximo de trazas en memoria
policies:
- name: politica-errores
type: status_code
status_code: {status_codes: [ERROR]}
- name: politica-trazas-lentas
type: latency
latency: {threshold_ms: 1000}
- name: politica-por-defecto
type: probabilistic
probabilistic: {sampling_percentage: 2}
Con esta configuración, el Collector:
- Conservará siempre las trazas que contengan un span con error
- Conservará siempre las trazas que tardaron más de 1 segundo
- Conservará el 2% del resto
Puedes combinar múltiples políticas con operadores and/or, filtrar por atributos específicos, apuntar a servicios individuales, o incluso enrutar diferentes poblaciones de trazas a diferentes backends.
Combinando Ambos: Sampling por Capas
Para sistemas de muy alto volumen, puedes usar head sampling y tail sampling juntos. El patrón habitual es:
- Head sampling en el SDK (o en un Collector gateway) para reducir el volumen inicial a un nivel manejable — por ejemplo, el 10% de todas las trazas
- Tail sampling en un segundo Collector para aplicar reglas inteligentes sobre ese volumen reducido
Esto protege al tail sampler de verse sobrecargado mientras sigue ofreciendo filtrado basado en calidad sobre lo que pasa.
Una Estrategia de Sampling Práctica
Aquí hay una configuración realista para un sistema de microservicios en producción con volúmenes de tráfico mixtos:
receivers:
otlp:
protocols:
grpc:
endpoint: 0.0.0.0:4317
processors:
tail_sampling:
decision_wait: 15s
num_traces: 200000
policies:
# 1. Nunca descartar errores — siempre investigar
- name: conservar-errores
type: status_code
status_code: {status_codes: [ERROR]}
# 2. Nunca descartar trazas lentas — las violaciones de SLO importan
- name: conservar-trazas-lentas
type: latency
latency: {threshold_ms: 500}
# 3. Conservar todas las trazas de servicios desplegados recientemente
- name: escrutinio-nuevo-despliegue
type: string_attribute
string_attribute:
key: deployment.version
values: ["v2.4.0"]
# 4. Por defecto: 1% para tráfico saludable y rápido
- name: linea-base
type: probabilistic
probabilistic: {sampling_percentage: 1}
exporters:
otlp:
endpoint: tu-backend:4317
service:
pipelines:
traces:
receivers: [otlp]
processors: [tail_sampling]
exporters: [otlp]
Esta configuración logra lo que el sampling al 100% nunca podría: garantiza que capturas cada error y cada request que viola el SLO, mientras reduce drásticamente el volumen (y el coste) del tráfico rutinario y saludable.
El Modelo Mental Correcto
El sampling no es recortar esquinas. Es hacerse la pregunta correcta:
¿Qué datos necesito para responder mis preguntas a las 3 de la mañana?
No necesitas la traza del request número 10.000 del mismo /health exitoso. Necesitas la traza del request que falló. Necesitas la traza que tardó 4 segundos cuando todo lo demás tardó 40ms. Necesitas la traza del nuevo despliegue que empezó a misbehave.
El head sampling te da cobertura estadística. El tail sampling te da visibilidad dirigida a lo que importa. El OpenTelemetry Collector te da la infraestructura para implementar ambos sin modificar una línea de código de aplicación.
El resultado: menores costes, mejor ratio señal-ruido, y la misma (o mejor) capacidad para depurar tus sistemas.
Qué Viene Después
Si quieres profundizar:
- La documentación de sampling de OpenTelemetry cubre la terminología oficial y las opciones en detalle
- La documentación del Tail Sampling Processor muestra todos los tipos de políticas disponibles
- Para el camino de head sampling, la documentación del Probabilistic Sampler cubre las opciones de configuración
Si todavía estás decidiendo qué señales recopilar antes de preocuparte por el sampling, lee Los 5 tipos de señales de OpenTelemetry para tener el panorama completo.