Principle:Langfuse Langfuse Trace Sampling
| Knowledge Sources | |
|---|---|
| Domains | Observability, Trace Ingestion |
| Last Updated | 2026-02-14 00:00 GMT |
Overview
Trace sampling is the technique of deterministically selecting a subset of traces for processing based on a configurable per-project sampling rate, ensuring consistent inclusion or exclusion of all events belonging to the same trace.
Description
In high-throughput production environments, processing every single trace can impose significant infrastructure costs for storage (ClickHouse, S3), queue throughput (Redis/BullMQ), and worker compute. Trace sampling allows operators to reduce this load by specifying that only a fraction of traces should be fully processed, while the remainder are dropped early in the pipeline.
The key properties of a good trace sampling mechanism are:
- Determinism: The same trace ID must always produce the same sampling decision. This ensures that if a trace's creation event is sampled in, all subsequent observation and score events for that trace are also sampled in. Without determinism, partial traces would appear in the system, which is worse than no trace at all.
- Uniform distribution: The sampling function must distribute trace IDs uniformly across the sample space. If certain trace ID patterns were systematically favored or excluded, the sample would be biased and not representative of overall system behavior.
- Per-project configuration: Different projects may have vastly different trace volumes and importance levels. A high-traffic production project might need aggressive sampling (e.g., 0.1 = 10% of traces), while a low-traffic development project should keep all traces (default behavior).
- Fail-open behavior: If the sampling configuration is missing, invalid, or the sample rate is out of range, the system defaults to including the trace. This conservative approach ensures no data is accidentally lost due to misconfiguration.
Usage
Apply trace sampling when:
- A project generates more trace data than can be cost-effectively stored and processed.
- You want to reduce infrastructure costs for high-volume projects without disabling tracing entirely.
- You need representative sample data for analytics rather than complete data for every trace.
- You are operating in a multi-tenant environment where different tenants have different data volumes.
Do not apply trace sampling when:
- Complete trace coverage is required for compliance or auditing purposes.
- The project volume is low enough that full processing is affordable.
- Individual trace completeness is critical for debugging specific issues.
Theoretical Basis
The sampling algorithm uses consistent hashing via SHA-256 to map trace IDs to a uniform probability space.
Algorithm
FUNCTION isTraceIdInSample(projectId, event):
sampledProjects = LOAD_FROM_ENV("LANGFUSE_INGESTION_PROCESSING_SAMPLED_PROJECTS")
IF projectId is null OR projectId not in sampledProjects:
RETURN { isSampled: true, isSamplingConfigured: false }
-- Project has no sampling config; process all events.
sampleRate = sampledProjects[projectId]
IF sampleRate is undefined:
RETURN { isSampled: true, isSamplingConfigured: true }
traceId = EXTRACT_TRACE_ID(event)
IF traceId is null:
RETURN { isSampled: true, isSamplingConfigured: true }
-- Cannot determine trace ID; be conservative and include.
RETURN { isSampled: isInSample(traceId, sampleRate), isSamplingConfigured: true }
FUNCTION isInSample(traceId, sampleRate):
IF sampleRate < 0 OR sampleRate > 1:
LOG_ERROR("Invalid sample rate")
RETURN true -- Fail open for invalid config
IF sampleRate == 0: RETURN false -- Drop all
IF sampleRate == 1: RETURN true -- Keep all
hash = SHA256(traceId)
hashInt = PARSE_HEX(hash[0..7]) -- First 4 bytes = 32-bit integer
normalizedHash = hashInt / 0xFFFFFFFF -- Normalize to [0, 1]
RETURN normalizedHash < sampleRate
Properties
- Determinism: SHA-256 is a deterministic function. Given the same trace ID, it always produces the same hash, and therefore the same sampling decision.
- Uniformity: SHA-256 output is cryptographically uniform across the output space. Truncating to 32 bits and normalizing to [0, 1] preserves this uniformity with a resolution of approximately 1 part in 4.3 billion.
- Independence from event type: The trace ID is extracted consistently regardless of whether the event is a trace-create (where the trace ID is the body's
idfield) or an observation/score event (where the trace ID is the body'straceIdfield). - No state required: The sampling decision is computed purely from the trace ID and sample rate, requiring no distributed state or coordination.
Trace ID Extraction
FUNCTION EXTRACT_TRACE_ID(event):
IF event.type == "trace-create":
RETURN event.body.id
ELSE IF event.body has field "traceId":
RETURN event.body.traceId
ELSE:
RETURN null