Headline: Next.js's instrumentation.ts file and its onRequestError hook give the App Router real distributed tracing and centralized error reporting, but Vercel Fluid Compute reusing one warm instance across concurrent requests means any request state stored outside OpenTelemetry's own context propagation — a module-level variable, a naive "current request" global — leaks between unrelated users' traces.

Key takeaways

register(), exported from instrumentation.ts, runs once when a server instance boots, not once per request — that's exactly where a tracing SDK belongs, and exactly why request-scoped state can't live there.

@vercel/otel's registerOTel() wraps the Node OpenTelemetry SDK with sane defaults for exporters and span processors, cutting most of the boilerplate a manual setup needs.

onRequestError, stable since Next.js 15, catches errors from Server Components, Route Handlers, Server Actions, and Middleware before Next.js renders its own error response — a component-level try/catch only ever sees its own subtree.