> ## Documentation Index
> Fetch the complete documentation index at: https://sentrydocs.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Profiling

> Find performance bottlenecks down to the function level

Profiling samples your application's call stack at regular intervals to build a picture of where time is actually being spent. Unlike transaction spans — which only measure code you explicitly instrument — profiling captures everything: every function call, every library, every frame on the stack.

## How profiling works

The profiler attaches to your running application and records the active call stack many times per second. Sentry aggregates those samples into a **flame graph** — a visual representation where each row is a function and width indicates how much time was spent there (or in functions it called).

This makes it easy to spot:

* Functions that consume a disproportionate amount of CPU time
* Unexpected library calls in hot paths
* Recursive patterns or inefficient algorithms

## Flame graphs

A flame graph shows your call stack with the widest bars being the most expensive. You can:

* **Click** on any frame to zoom into that subtree
* **Search** for a specific function name to highlight all its occurrences
* **Sort** by self time (time spent in the function itself) or total time (including callees)

Profiles are linked directly from their parent transaction — open a slow transaction in Performance Monitoring and click the **Profiling** tab to see the flame graph for that specific execution.

## Differential profiles

The **Differential Profile** view compares two profiles side-by-side — typically between two releases. Red frames got slower; green frames got faster. This makes regressions introduced by a specific deploy immediately visible.

## Enabling profiling

Add `profilesSampleRate` to your `Sentry.init` call alongside your `tracesSampleRate`:

<CodeGroup>
  ```javascript JavaScript (Browser / Node.js) theme={null}
  import * as Sentry from "@sentry/browser";

  Sentry.init({
    dsn: "https://your-dsn@sentry.io/project-id",

    // Profiling requires tracing to be enabled
    tracesSampleRate: 1.0,

    // Sample 100% of profiled transactions
    profilesSampleRate: 1.0,
  });
  ```

  ```python Python theme={null}
  import sentry_sdk

  sentry_sdk.init(
      dsn="https://your-dsn@sentry.io/project-id",

      # Profiling requires tracing to be enabled
      traces_sample_rate=1.0,

      # Sample 100% of profiled transactions
      profiles_sample_rate=1.0,
  )
  ```
</CodeGroup>

<Note>
  Profiling is sampled on top of tracing. A transaction must be sampled by `tracesSampleRate` first; then `profilesSampleRate` determines what fraction of those sampled transactions also get a profile. To profile 10% of all transactions, set both to `1.0` and `tracesSampleRate` to `0.1`.
</Note>

## Supported platforms

| Platform               | Package                                                 |
| ---------------------- | ------------------------------------------------------- |
| **Browser JavaScript** | `@sentry/browser`, `@sentry/react`, `@sentry/vue`, etc. |
| **Node.js**            | `@sentry/node`                                          |
| **Python**             | `sentry-sdk`                                            |
| **Java / Android**     | `sentry-android`                                        |
| **iOS / macOS**        | `sentry-cocoa`                                          |

<Warning>
  Browser profiling uses the [JS Self-Profiling API](https://wicg.github.io/js-self-profiling/) which requires your page to send a `Document-Policy: js-profiling` HTTP header. Check browser compatibility before enabling in production.
</Warning>

## Viewing profiles

<Steps>
  <Step title="From a transaction">
    Open any transaction in the **Performance** section. If a profile was captured, a **Profiling** tab appears in the transaction detail. Click it to view the flame graph for that specific execution.
  </Step>

  <Step title="From the Profiling section">
    Navigate to **Profiling** in the left sidebar to browse all captured profiles. Filter by transaction name, release, environment, or date range. From here you can also access the **Functions** view — a table ranking every function by its aggregate impact across all profiles.
  </Step>

  <Step title="Differential profiles">
    In the Profiling section, select two profiles and choose **Compare** to open the differential view. Use the release filter to quickly compare profiles from two different deploys.
  </Step>
</Steps>

## Continuous profiling

In addition to transaction-based profiling, Sentry supports **continuous profiling** for long-running processes (background workers, daemons, server processes). Continuous profiling runs the sampler independently of transactions, so you get coverage even for work that doesn't map to a discrete request.

Enable it in Node.js with:

```javascript theme={null}
import * as Sentry from "@sentry/node";

Sentry.init({
  dsn: "https://your-dsn@sentry.io/project-id",
  profileSessionSampleRate: 1.0, // Continuous profiling sample rate
});
```
