Sampling
Sampling controls which traces are exported. The TypeScript SDK supports head sampling and tail sampling.
Head sampling makes a probabilistic decision when a trace starts:
import * as logfire from '@pydantic/logfire-node'
logfire.configure({
sampling: { head: 0.1 },
serviceName: 'checkout-api',
})
In Node.js, LOGFIRE_TRACE_SAMPLE_RATE=0.1 configures head sampling from the environment. The value must read as a number between 0 and 1; anything else makes configure() throw rather than silently exporting every trace. An explicit sampling option takes precedence over the environment variable.
Tail sampling can keep traces based on span level or duration:
logfire.configure({
sampling: logfire.levelOrDuration({
durationThreshold: 2.0,
levelThreshold: 'warning',
}),
serviceName: 'checkout-api',
})
You can also provide a callback:
logfire.configure({
sampling: {
tail: (spanInfo) => {
if (spanInfo.level.gte('error')) return 1.0
if (spanInfo.duration > 1.5) return 1.0
return 0.0
},
},
serviceName: 'worker',
})
Tail sampling buffers spans until a decision can be made. Be conservative in browsers and long-lived processes because buffering can increase memory usage.
In Node.js, pending-span placeholders respect tail-sampling decisions: accepted traces can emit pending placeholders for still-open spans, while dropped traces do not export pending placeholders.
See examples/node/sampling.ts for a runnable example.