Trasys
Node.js SDK

Sampling

Control which requests get recorded to manage data volume and cost — set per-route rates, and AI calls and debug users are always kept regardless of rate.

Sampling

A busy service can handle thousands of requests per second, and most of them look identical — a health check returning 200 a thousand times tells you nothing new after the first few. Sampling lets you record less of the noisy, repetitive traffic while keeping everything that actually matters.

Sampling is applied at the span level: if a request is dropped, none of its child spans (AI calls, DB queries) are recorded either.

Setting rates

createSdk({
  sampling: {
    default: 1.0, // record 100% of requests not covered below
    routes: {
      '/api/health': 0.01, // 1% — called by load balancers constantly
      '/api/ping':   0.01, // 1% — same
      '/api/search': 0.10, // 10% — high volume, largely repetitive
    },
  },
});

default and each entry in routes are a probability from 0.0 (record nothing) to 1.0 (record everything).

Route matching

A route in routes doesn't need to match exactly — the SDK also does prefix matching, picking the longest configured prefix that matches the incoming route:

sampling: {
  routes: {
    '/api/users': 0.05, // matches /api/users, /api/users/orders, /api/users/:id/orders, etc.
  },
}

If a route matches nothing in routes, it falls back to default.

What's always recorded, regardless of rate

Two categories bypass the rate check entirely and are always kept:

Every AI span. Any span that made an LLM call is recorded no matter what sampling rate applies to its route — these are infrequent relative to regular HTTP traffic and are the core of what Trasys tracks, so they're never subject to rate-based dropping.

Requests from specific users you're debugging:

createSdk({
  sampling: {
    alwaysRecordUserIds: ['usr_problematic_customer'],
  },
});

Every request from a listed user ID is recorded at 100%, regardless of route or rate. This is useful when a specific customer reports a bug and you need full visibility into everything they do — clear the list once you're done, since leaving users here in production increases data volume unexpectedly.

The decision order

For every request, the sampler decides in this order:

1. Is the route in ignoreRoutes (/health, /ping, etc.)?
      YES → drop immediately, nothing else is checked

2. Is this an AI span, or a request from an alwaysRecordUserIds user?
      YES → record it, the rate is never consulted

3. Look up the sampling rate for this route (exact match, then longest prefix, then default)
      Flip a weighted coin at that probability → record or drop

ignoreRoutes is checked first specifically because those routes tend to be called far more often than anything else (load balancer health checks running thousands of times a minute) and are never useful to record — skipping them before any other check avoids doing unnecessary work on the highest-volume traffic you have.


Next steps

  • Metrics — custom counters/gauges/histograms are unaffected by request sampling
  • AI Observability — why AI spans are exempt from sampling
  • Installation & Setup — the full config reference, ignoreRoutes included

On this page