# Set Up Java Profiling | Sentry for Spring

With [profiling](https://docs.sentry.io/product/explore/profiling.md), Sentry tracks your software's performance by sampling your program's call stack in a variety of environments. This feature collects function-level information about your code and enables you to fine-tune your program's performance. [Sentry's profiler](https://sentry.io/for/profiling/) captures function calls and their exact locations, aggregates them, and shows you the most common code paths of your program. This highlights areas you could optimize to help increase both the performance of your code and increase user satisfaction, as well as drive down costs.

Continuous profiling is available starting in SDK version `8.23.0` for macOS and Linux.

Versions < `8.26.0` use [async-profiler](https://github.com/async-profiler/async-profiler) in version 3 and thus only support Java up to JDK 22. Starting with `8.26.0` we upgraded to [async-profiler](https://github.com/async-profiler/async-profiler) 4.2 enabling support for all Java versions up to JDK 25.

## [Install](https://docs.sentry.io/platforms/java/guides/spring/profiling.md#install)

In addition to your typical Sentry dependencies, you will need to add `sentry-async-profiler` as a dependency:

```groovy
implementation 'io.sentry:sentry-async-profiler:8.33.0'
```

## [Enabling Continuous Profiling](https://docs.sentry.io/platforms/java/guides/spring/profiling.md#enabling-continuous-profiling)

Continuous Profiling supports two modes: `manual` and `trace`. These modes are mutually exclusive and cannot be used at the same time.

In `manual` mode, the profiling data collection can be managed via calls to `Sentry.startProfiler()` and `Sentry.stopProfiler()`. You are entirely in control of when the profiler runs.

In `trace` mode, the profiler manages its own start and stop calls, which are based on spans: the profiler continues to run while there is at least one active span, and stops when there are no active spans.

### [Enabling Trace Lifecycle Profiling](https://docs.sentry.io/platforms/java/guides/spring/profiling.md#enabling-trace-lifecycle-profiling)

To enable trace profiling, set the lifecycle to `TRACE`. Trace profiling requires tracing to be enabled.

Check out the [tracing setup documentation](https://docs.sentry.io/platforms/java/guides/spring/tracing.md) for more detailed information on how to configure sampling. Setting the sample rate to 1.0 means all transactions will be captured.

`application.properties`

```properties
sentry.traces-sample-rate=1.0
sentry.profile-session-sample-rate=1.0
sentry.profile-lifecycle=TRACE
```

### [Enabling Manual Lifecycle Profiling](https://docs.sentry.io/platforms/java/guides/spring/profiling.md#enabling-manual-lifecycle-profiling)

To enable manual profiling, set the lifecycle to `MANUAL`. Manual profiling does not require tracing to be enabled.

`application.properties`

```properties
sentry.profile-session-sample-rate=1.0
sentry.profile-lifecycle=MANUAL
```

Then use the `startProfiler` and `stopProfiler` methods to start and stop profiling respectively.

```java
import io.sentry.Sentry;

// Start profiling
Sentry.startProfiler();

// run some code here

// Stop profiling
Sentry.stopProfiler();
```

### [Profiling with OpenTelemetry](https://docs.sentry.io/platforms/java/guides/spring/profiling.md#profiling-with-opentelemetry)

When running our OpenTelemetry Agent in [Agent Auto-Init](https://docs.sentry.io/platforms/java/guides/spring/opentelemetry/setup/agent/auto-init.md) mode. The `SentryProfilerConfiguration` needs to be setup. This is due to the fact that the profiler is not yet on the classpath when the agent initializes `Sentry`. Therefore the profiler needs to be initialized when `Spring` starts.

If you are using our OpenTelemetry Agent, profiling when running in the [Agent Auto-Init](https://docs.sentry.io/platforms/java/guides/spring/opentelemetry/setup/agent/auto-init.md) mode is supported from version `8.26.0` onwards.

In order to set this up, import `SentryProfilerConfiguration` in one of your `@Configuration` classes:

```java
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Import;
+import io.sentry.spring.SentryProfilerConfiguration;

+@Import(SentryProfilerConfiguration.class)
class SentryConfig {
}
```

### [Managing Profile Sampling Rates](https://docs.sentry.io/platforms/java/guides/spring/profiling.md#managing-profile-sampling-rates)

Sentry SDK supports an additional `profileSessionSampleRate` that must be set to a non-zero value to enable continuous profiling. This can be used to control session sampling rates at the service level as the sampling decision is evaluated only once at SDK initialization.

This is useful for cases where you deploy your service many times, but would only like a subset of those deployments to be profiled. In a single service environment we recommend to set this to 1.0.

### [Manage Storage Location for Profiles](https://docs.sentry.io/platforms/java/guides/spring/profiling.md#manage-storage-location-for-profiles)

The files generated by the underlying profiler are temporarily stored. By default we use the directory `System.getProperty("java.io.tmpdir")/profiling_traces`. This path can be configured by setting the `profilingTracesDirPath` option.

## [Platform Support](https://docs.sentry.io/platforms/java/guides/spring/profiling.md#platform-support)

Continuous profiling for Java is currently supported on:

* macOS
* Linux

The profiler uses [async-profiler](https://github.com/async-profiler/async-profiler) under the hood to collect profiling data.
