instrumentation.ts: Startup Hooks & OpenTelemetry Tracing Spans
- Last updated
- Prerequisites:
- Distributed tracing basics
- OpenTelemetry (OTel) core concepts
- nextjs
- opentelemetry
- instrumentation
- tracing
- monitoring
- apm
Read at your depth
The practical view
`instrumentation.ts` (placed in the root of your project) exports a `register()` function that Next.js runs once whenever a new server instance boots up. It is the official place to initialize monitoring SDKs (like Sentry, Datadog, or OpenTelemetry), connect to database pools, or set up tracing spans without polluting your UI code.
The same idea in other frameworks
Custom APM init scripts executed before `ReactDOM.hydrateRoot()`.Angular `APP_INITIALIZER` token for bootstrap telemetry setup.Nuxt Nitro server plugins in `server/plugins/` running on engine startup.SvelteKit `hooks.server.ts` `init()` function.Legacy vs modern
Ad-hoc Global Logging vs Centralized OpenTelemetry Registration
Importing telemetry in root layouts causes multiple initializations; `instrumentation.ts` guarantees clean single-pass server boot execution.
if (!global.tracer) initTracer(); // ❌ OLD: Pollutes render path and runs per-requestexport async function register() { await initOpenTelemetry(); } // ✅ NEWInterview gotchas
Context
Interviewers test your knowledge of multi-runtime execution (Edge vs Node.js).
The mechanical answer
`instrumentation.ts` is compiled for *all* runtimes used by Next.js, including the Edge Runtime. Because heavy monitoring packages (like `@opentelemetry/sdk-node`) rely on Node.js core modules (`fs`, `net`, `async_hooks`), static imports would fail in the Edge environment. Using dynamic `import()` inside a `process.env.NEXT_RUNTIME === 'nodejs'` conditional ensures Node packages are only loaded when running on the Node.js server.
Trap
Top-level static imports of Node.js modules in `instrumentation.ts` will crash your Edge Runtime routes during build.
Context
This tests framework convention awareness.
The mechanical answer
`instrumentation.ts` (or `.js`) must be located in the root of your project directory (or inside the `src/` directory if you are using `src/app`). It should sit directly adjacent to your `app/` or `pages/` directory.
Trap
Placing it inside `app/instrumentation.ts` is invalid and Next.js will ignore it.