← Home ← Codex ← DEBT ← Engine
Browse by Category
+ added · updated 7d
← Back to glossary

Log Sampling Strategies

Observability Intermediate
debt(d7/e5/b5/t7)
d7 Detectability Operational debt — how invisible misuse is to your safety net

Closest to 'only careful code review or runtime testing' (d7). Detection hints list collector/pipeline tools (opentelemetry-collector, vector, fluent-bit) that can observe volume but can't automatically flag missing sample_rate stamps or inconsistent sampling decisions; automated=no confirms this needs human review or billing surprises to surface.

e5 Effort Remediation debt — work required to fix once spotted

Closest to 'touches multiple files / significant refactor in one component' (e5). The quick_fix (tiered rates + stamp sample_rate on every event) requires updating logger config plus every emission site and downstream dashboards to scale counts back up — more than a one-line patch but usually scoped to the logging layer.

b5 Burden Structural debt — long-term weight of choosing wrong

Closest to 'persistent productivity tax' (b5). applies_to spans web/cli/queue/node, and sampling decisions must stay consistent across services and be honored by dashboards, alerts, and trace correlation, so many work streams have to reason about it, though it doesn't define system shape.

t7 Trap Cognitive debt — how counter-intuitive correct behaviour is

Closest to 'serious trap (contradicts how a similar concept works elsewhere)' (t7). The misconception ('sampling loses debugging data, never sample') and common_mistakes (flat rates dropping errors, unstamped events making dashboards lie, inconsistent cross-service decisions) show the naive mental model is actively wrong in ways that silently corrupt metrics.

About DEBT scoring →

Also Known As

log sampling logging sample rate adaptive logging

TL;DR

Techniques for reducing log volume by emitting only a representative subset, balancing cost against debugging fidelity.

Explanation

Log sampling is the practice of writing only a fraction of eligible log events to disk or a downstream aggregator, chosen so the retained subset still reflects system behaviour. High-traffic services produce logs faster than humans, storage, or search indexes can absorb - sampling caps that firehose while preserving the signals engineers actually query. Common strategies fall into three families. (1) Head-based (upfront) sampling: decide at request entry whether to log this trace or drop it. Probabilistic head sampling (e.g. keep 1 in 100) is trivial to implement and gives predictable volume, but can miss rare errors. (2) Tail-based sampling: buffer events for a request and decide after completion - keep everything for errors, slow requests, or specific tenants, drop routine successes. This preserves debugging value but requires buffering infrastructure. (3) Deterministic/consistent sampling: hash a trace or user id and keep events whose hash falls in a chosen bucket. Two services making the same decision on the same id means correlated logs stay together across a distributed trace. Additional techniques layer on top: rate limiting per log key (log the first N of each error signature per minute), reservoir sampling for unbounded streams, priority sampling that always keeps ERROR/WARN and samples INFO/DEBUG, and dynamic sampling that adjusts rate based on current volume or cost budget. The critical design rule: always retain 100% of errors, security events, and audit records. Sample the boring stuff. Record the effective sample rate as a field on every emitted event so aggregations can multiply back up to true counts. Without that, dashboards silently under-report.

Common Misconception

Sampling loses debugging data, so you should never sample production logs. In practice, unsampled high-volume logs get dropped by rate limiters, priced out of retention, or become unsearchable - selective sampling with 100% error retention gives better debuggability than unsampled logs that no one can afford to keep for more than a day.

Why It Matters

Log ingest is often the single largest observability cost, and unbounded volume leads to dropped events, slow queries, and abandoned dashboards. Thoughtful sampling keeps the observability platform affordable and fast while preserving the events that matter for incident response.

Common Mistakes

  • Applying a flat probabilistic rate to all events, so rare errors and security-relevant events get dropped alongside routine traffic.
  • Not recording the sample rate on emitted events, causing dashboards and alerts to report artificially low counts.
  • Using inconsistent sampling decisions across services in a trace, so logs for the same request appear in one service but not the next.
  • Sampling before applying rate limits, so a single noisy log line still floods the pipeline just at a lower percentage.
  • Head sampling without any tail-based override for errors, missing the exact requests that engineers need to investigate.

Avoid When

  • Audit, compliance, or security event logs where regulators require complete records.
  • Low-volume services where full logging is affordable and every event has debugging value.
  • Financial or transactional flows where every state transition must be reconstructible.

When To Use

  • High-throughput HTTP or RPC services where per-request INFO logs dominate ingest cost.
  • Distributed traces where consistent sampling across services keeps correlated events together.
  • Debug or verbose logging in production where a small representative sample is enough for trend analysis.
  • When observability spend is capped and you must choose between sampling or dropping entire log streams.

Code Examples

✗ Vulnerable
// Flat 1% sampling - drops 99% of errors too
if (Math.random() < 0.01) {
    logger.info('request', { path, status, duration });
}
// Errors get dropped at the same rate as successes.
// No sample_rate field, so downstream counts are wrong.
if (Math.random() < 0.01) {
    logger.error('payment_failed', { orderId, err });
}
✓ Fixed
// Priority + consistent sampling with rate metadata
// hash() = any stable 32-bit hash, e.g. FNV-1a or xxhash of the string traceId
function sampleRate(level, traceId) {
    if (level === 'error' || level === 'warn') return 1.0;
    if (level === 'info')  return 0.1;
    return 0.01; // debug
}

function shouldEmit(level, traceId) {
    const rate = sampleRate(level, traceId);
    // Deterministic: same traceId => same decision across services
    const bucket = (hash(traceId) % 10000) / 10000;
    return { keep: bucket < rate, rate };
}

const { keep, rate } = shouldEmit(level, ctx.traceId);
if (keep) {
    logger.log(level, msg, { ...fields, sample_rate: rate, trace_id: ctx.traceId });
}
// Downstream: true_count = count(*) * avg(1/sample_rate)

Added 20 Sep 2026
Views 11
Rate this term
No ratings yet
🤖 AI Guestbook educational data only
| |
Last 30 days
0 pings W 0 pings T 0 pings F 0 pings S 0 pings S 0 pings M 0 pings T 0 pings W 0 pings T 0 pings F 0 pings S 0 pings S 0 pings M 0 pings T 0 pings W 0 pings T 0 pings F 0 pings S 0 pings S 0 pings M 0 pings T 0 pings W 0 pings T 0 pings F 0 pings S 4 pings S 1 ping M 0 pings T 1 ping W 0 pings T
No pings yet today
Ahrefs 1
Google 3 Bing 1 PetalBot 1 Ahrefs 1
crawler 6
DEV INTEL Tools & Severity
🟡 Medium ⚙ Fix effort: Medium
⚡ Quick Fix
Keep 100% of ERROR and WARN, sample INFO at 10%, sample DEBUG at 1%, and stamp every emitted event with its sample_rate field so aggregations can scale back up.
📦 Applies To
web cli queue-worker node
🔗 Prerequisites
🔍 Detection Hints
logger\.(info|debug|log)\([^)]*\)(?![^\n]*sample_rate)
Auto-detectable: ✗ No opentelemetry-collector vector fluent-bit grafana-agent
⚠ Related Problems
🤖 AI Agent
Confidence: Medium False Positives: Medium ✗ Manual fix Fix: Medium Context: File Tests: Update


✓ schema.org compliant