---
title: Instrumentation
description: Learn how to use instrumentation to run code at server startup in your Next.js app
url: "https://nextjs.org/docs/14/app/building-your-application/optimizing/instrumentation"
version: 14.2.35
lastUpdated: 2024-03-13
prerequisites:
  - "Building Your Application: /docs/14/app/building-your-application"
  - "Optimizing: /docs/14/app/building-your-application/optimizing"
---


Instrumentation is the process of using code to integrate monitoring and logging tools into your application. This allows you to track the performance and behavior of your application, and to debug issues in production.

Next.js provides a `register` function that can be exported from a `instrumentation.ts|js` file in the **root directory** of your project (or inside the `src` folder if using one). Next.js will then call `register` whenever a new Next.js server instance is bootstrapped.

When your `register` function is deployed, it will be called on each cold boot (but exactly once in each environment).

Sometimes, it may be useful to import a file in your code because of the side effects it will cause. For example, you might import a file that defines a set of global variables, but never explicitly use the imported file in your code. You would still have access to the global variables the package has declared.

You can import files with side effects in `instrumentation.ts`, which you might want to use in your `register` function as demonstrated in the following example:

```ts filename="your-project/instrumentation.ts" switcher
import { init } from 'package-init'

export function register() {
  init()
}
```

```js filename="your-project/instrumentation.js" switcher
import { init } from 'package-init'

export function register() {
  init()
}
```

However, we recommend importing files with side effects using `import` from within your `register` function instead. The following example demonstrates a basic usage of `import` in a `register` function:

```ts filename="your-project/instrumentation.ts" switcher
export async function register() {
  await import('package-with-side-effect')
}
```

```js filename="your-project/instrumentation.js" switcher
export async function register() {
  await import('package-with-side-effect')
}
```

By doing this, you can colocate all of your side effects in one place in your code, and avoid any unintended consequences from importing files.

We call `register` in all environments, so it's necessary to conditionally import any code that doesn't support both `edge` and `nodejs`. You can use the environment variable `NEXT_RUNTIME` to get the current environment. Importing an environment-specific code would look like this:

```ts filename="your-project/instrumentation.ts" switcher
export async function register() {
  if (process.env.NEXT_RUNTIME === 'nodejs') {
    await import('./instrumentation-node')
  }

  if (process.env.NEXT_RUNTIME === 'edge') {
    await import('./instrumentation-edge')
  }
}
```

```js filename="your-project/instrumentation.js" switcher
export async function register() {
  if (process.env.NEXT_RUNTIME === 'nodejs') {
    await import('./instrumentation-node')
  }

  if (process.env.NEXT_RUNTIME === 'edge') {
    await import('./instrumentation-edge')
  }
}
```
---

For an index of all available documentation, see [/docs/14/llms.txt](/docs/14/llms.txt)