What is collected by default
Without any of these switches:- SQL is normalized before it leaves your server.
where id = 42is captured aswhere id = ?, and the bind values are discarded in-process — they are never transmitted or stored. - Redis and cache keys are masked to their shape —
user:9f31:profilebecomesuser:?:profile. - Spans do carry the code that started them (see Code location); switching it off removes the location, the function name and the stack from every span.
Statement text is stored only for accounts that opt in
The SDK sends the normalized statement and the caller stack with each span, but ApiTraffic stores and shows them only for accounts with statement text enabled. For every other account they are removed before the request is stored, and removed again whenever a request is read, so the request page, shared links, embeds, workflows, the API and the MCP tools all show the operation, its fingerprint and its code location without the query text. This also applies to the statement as issued and its bind values from Query parameters: that capture only shows anything for an account with statement text enabled. Operators can switch statement text off for every account at once. Requests stored before this rule had text attached; it is withheld on read in the same way. Opting out is final for the text captured until then: when an account turns statement text off, the moment is recorded, and text captured before it (plus a two-minute grace for servers that had not yet seen the change) is never shown again, even if the account later opts back in. Span reports over a window that reaches back before that moment show only the statement text captured since.Turning capture on for a bucket
1
Open the bucket
Go to Bucket Settings and select the APM Capture tab.
2
Enable what you need
Turn on Collect SQL statements with their parameters and/or Collect concrete Redis and cache
keys. Collect the code location that started each operation is already on, with a Stack
trace depth of 10 frames.
3
Choose an auto-disable window
Under Auto-Disable, pick 15 minutes, 1 hour, 4 hours, 24 hours, or Until I turn it off.
The page then shows the exact time capture stops. The window restarts each time you save, and
applies to the parameter and key switches only — never to code location.
4
Save
Connected servers pick the change up immediately over the realtime channel — no restart and no
deploy. Reproduce the problem, then let the window expire.
How the window is enforced
The expiry is applied in two independent places, so capture stops on time even if a server never reloads its settings and even if nobody returns to the dashboard:- the API stops reporting the switches as enabled on the SDK settings payload once the window passes, and
- each SDK arms its own timer and returns capture to the defaults at that exact moment.
Turning capture on in the SDK
The same switches exist as SDK options —captureStatementParams,
captureRedisKeys, captureCallSite and captureStackDepth, or their API_TRAFFIC_* environment
variables.
For the two privacy switches the effective setting is local OR bucket: a bucket switch turns
capture on for servers that have not enabled it locally, and a locally enabled switch is not
turned off when a bucket window expires.
Code location and its depth are owned by the bucket unless the application sets them
explicitly. Set captureCallSite: false (or captureStackDepth: 1) in code or the environment and
that wins everywhere; leave them alone and the dashboard is in charge, including switching capture
off. Prefer the bucket settings for production — they are reversible and do not need a deploy.
Code location
A span carriescallSite (for example src/services/orders.ts:142:9), callSiteFn, and
callStack — the callers above the call site, innermost first — shown in the span details as
Code location, Function and Stack trace. The stack is taken when the operation is
initiated, because a driver callback runs far from the caller.
Frames in Node internals, node_modules and the ApiTraffic packages are skipped, so the depth is
spent on the chain through your own code: the route handler that led to the query, not the driver
that ran it. Paths are relative to your application root, and transpiled projects report the built
file unless source maps are deployed.
Frames are read through V8’s structured stack API rather than by formatting and parsing a stack
string, which is what makes ten frames affordable as a default: measured per span, ~12 µs for ten
frames against ~16 µs for the single-frame string walk this replaced. The cost follows how deep the
stack actually is, not the depth you ask for — an operation issued through an ORM under an
instrumentation patch has far more library frames to walk past, and costs nearer ~30 µs.
Lower the depth if you are counting microseconds on a very hot path — 1 keeps the call site alone
— or switch it off entirely, in which case no stack is walked at all rather than walked and
discarded. If a span exceeds its metadata budget the outermost frames are dropped first, so the call
site always survives.
The location is also stored on the span row, so Code Location is available as a grouping in
Performance → Operations and not just in a single request. Where a
git integration has correlated a deploy to the request, the location links
to the file at the exact commit that was running — a permalink, never a branch, so it still points
at the right line after the code has moved on.
Managing capture over the API
The switches are fields on the bucket, so they can be driven from CI or a script as well as the dashboard.boolean
Allow spans to carry full SQL statements and their bind parameters.
boolean
Allow spans to carry concrete Redis and cache keys.
boolean
default:"true"
Whether spans carry the application file, line, function and caller chain that started the
operation.
false collects none of it.number
default:"10"
How many application frames to keep per span, innermost first (1–50).
1 keeps the call site
alone.string
ISO 8601 time (UTC) at which the parameter and Redis key switches stop applying.
null means they
stay on until turned off. Code location is unaffected.