Skip to content

Repository files navigation

Trace ID Entropy Lab

Your sampler says 10%. The incident cohort says 0%.

This interactive lab demonstrates a subtle probability-sampling failure: deterministic sampling can hit its fleet-wide target exactly while retaining no representative traces for most cohorts. The sampler arithmetic is correct; the trace ID randomness is not.

The executable model is a GNU Bison grammar compiled to C. A dependency-free Node.js service runs that model, renders the experiment, and exposes OTLP-shaped metrics, logs, and traces for inspection.

The experiment

Four strategies evaluate the same request population:

Strategy Randomness input What happens
Tenant suffix A cohort number encoded in the trailing trace-ID bits Global rate can look perfect while only one cohort is sampled
Low counter A monotonic value in the trailing bits Every request can fall below the rejection threshold
Random trace ID Uniform trailing randomness with the random flag set Sampling is distributed across every cohort
Explicit rv Randomness carried in OpenTelemetry tracestate Structured IDs can retain consistent probability semantics

The default scenario deliberately produces the most dangerous result: the structured generator samples exactly 10% overall, but covers only 1 of 10 cohorts and misses every error in the incident cohort.

OpenTelemetry's probability-sampling model compares a 56-bit randomness value R with a rejection threshold T. That randomness normally comes from the trailing seven bytes of the trace ID or from an explicit rv value in tracestate. See the Tracing SDK specification and probability-sampling specification. The W3C Trace Context Level 2 specification defines the corresponding trace-ID randomness requirements.

Why telemetry.sh helps

A dashboard that only checks the achieved sample rate cannot diagnose this failure. The lab emits evidence that can be correlated:

  • trace.sampling.actual
  • trace.sampling.cohort.coverage
  • trace.sampling.error.recall
  • trace.sampling.adjusted_count.bias
  • trace.sampling.error_estimate.bias
  • warning and error logs describing unconfirmed randomness
  • sampler evaluation spans with the random flag and explicit-randomness provenance

The result is a queryable explanation of why the retained traces are not representative—not merely a count of how many survived.

Run locally

Requirements:

  • GNU Bison
  • a C99 compiler
  • GNU Make
  • Node.js 20 or newer
npm ci
make check
make run

Open http://127.0.0.1:3000.

Useful endpoints:

GET /api/simulate
GET /api/telemetry
GET /healthz

All model inputs can be supplied as query parameters:

/api/simulate?cohorts=16&requests=1000&ratio=5&hot=7&hotError=35&seed=91

Run with Docker

docker compose up --build

Then open http://127.0.0.1:3000.

Model DSL

The browser controls produce this compact scenario language:

COHORTS 10
REQUESTS 500
RATIO 10
HOT 3
HOT_ERROR 24
BASE_ERROR 1
SEED 73
RUN

The grammar lives in model/sampler.y. make build asks Bison to generate a parser and compiles the result into build/sampler-model. Generated sources and binaries are intentionally excluded from Git.

Architecture

browser controls
      │
      ▼
Node.js HTTP service ── scenario DSL ──▶ GNU Bison model
      │                                      │
      ├── interactive cohort view ◀──────────┤
      └── OTLP-shaped metrics/logs/spans ◀───┘

No database, framework, CDN, or third-party JavaScript package is required.

Safety

This is a deterministic educational simulation. It creates no external traffic and exports no telemetry. The OTLP-shaped payload is available locally so the signal design can be inspected without credentials.

License

MIT

About

Interactive GNU Bison lab exposing probability-sampling bias caused by low-entropy trace IDs.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages