Performance

A p95 chart tells you it’s slow. We tell you which query.

ApiTraffic records the work each Node handler caused - every query, cache call, outbound request and queue publish - and stores it with the request itself. Then it ranks every operation across your service, flags N+1s with the line of code, and shows what got slower after each deploy.

Span types

What gets captured, automatically

db.query

Postgres, MySQL, SQL Server, Oracle, MongoDB, Cassandra, DynamoDB

redis

redis and ioredis commands

cache

Memcached

http.out

fetch, undici and Node http - so axios and got too

queue

RabbitMQ, Kafka and the AWS SDK

rpc

gRPC, one setting away

graphql

Operations and resolvers, one setting away

custom

Anything you time yourself with span()

Waterfall

The N+1 you have been paying for since last year

One glance at a waterfall usually ends a week of speculation. Here, the same order_items query runs once per line item - and ApiTraffic has already flagged it on the operations list, with the file and line that runs it.

  • Every span on one timeline, with type, duration and outcome
  • Database, cache and application time split for every request
  • Open any span for its statement, table, rows, host and call stack
  • Ask AI for a fix, with the whole waterfall as context
Regressions

Did that release make anything slower?

Pick a deploy and ApiTraffic ranks the operations and endpoints that got slower after it - p95 before, p95 after, the change and the calls - weighted by traffic, so a small slowdown on a hot path comes first.

  • Compare around any deploy marker or a moment you pick
  • Open any row for its latency trend, heatmap and slowest real examples
Why Node teams switch

APM without the agent, the sampling, or the bill

Percentiles that mean something

p50, p95 and p99 per normalised endpoint over any window - not an average across your whole service that hides the endpoint your biggest customer uses.

Query-level attribution

See the statement, how many times a single request ran it, and how much of your p95 it owns. N+1 patterns surface as “43 calls / request”.

Upstream accountability

Outbound calls are captured with timing, so when a provider degrades you have the evidence in the support ticket you file.

Private by default

Statements are normalized (where id = ?). Bind values and Redis keys stay off unless you turn them on, for a limited window if you like.

Regressions after every deploy

Pick a deploy and see which operations and endpoints got slower after it, ranked by their impact on real traffic.

Ask AI about a waterfall

One click builds a prompt with every span, its timing, code location and call stack, plus the commit that was deployed.

No manual instrumentation

Spans come from OpenTelemetry auto-instrumentation via one preload - or add our span processor to the OpenTelemetry setup you already run.

Correlated with the request

Async context tracking attributes a pooled pg query or keep-alive response back to the request that started it - the part that is genuinely hard to get right in Node.

Setup

One preload flag. That’s the install.

The APM bridge attaches OpenTelemetry auto-instrumentation to the ApiTraffic SDK, so spans arrive already tied to the request that produced them. Nothing to deploy beside your app, no collector to operate. Already running OpenTelemetry? Add our span processor to your provider instead of instrumenting twice.

Sampled tracing answers “is something slow?”. Because capture here is per request, you can open the exact slow request a customer reported - not the one that happened to survive a 1% sample.

# Start APM before your app loads its database drivers
node -r @apitraffic/node/register ./server.js

Find the query that owns your p95 this week.

npm i the SDK, preload the APM bridge, and look at one waterfall. Free trial, no credit card.

Free trial · No credit card · Set up in minutes