Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion docs/platforms/android/configuration/options.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -353,6 +353,14 @@ UI Profiling requires SDK versions `8.7.0` or higher. Lower versions can use the

</Alert>

<SdkOption name="enableLegacyProfiling" type="bool" defaultValue="true" availableSince="8.47.0">

On devices running Android 15 (API level 35) or higher, UI Profiling always uses the Android <Link to="https://developer.android.com/reference/android/os/ProfilingManager">ProfilingManager</Link> to capture <Link to="https://perfetto.dev/">Perfetto</Link> traces. On older devices, this option controls whether the SDK falls back to the <PlatformLink to="/profiling/legacy">legacy `tracer` backend</PlatformLink>. When `true` (the default), the legacy profiler runs on devices below API level 35. Set it to `false` to disable profiling on those devices entirely.

This option is deprecated and will be removed in the next major release, when only the ProfilingManager (Perfetto) backend will remain.

@romtsn romtsn Jun 30, 2026

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
This option is deprecated and will be removed in the next major release, when only the ProfilingManager (Perfetto) backend will remain.
This option will be deprecated in the next major release and will be removed in the one after next, when only the ProfilingManager (Perfetto) backend will remain.

We continued the discussion while you were away and turns out there's still quite some usage of the old tracer among our biggest orgs, so we've decided to keep the option in the next major (turn it to false by default and deprecate it), and only remove the option and the legacy tracer in the one after. https://sentry.slack.com/archives/C089VFRB8N9/p1781857096845799?thread_ts=1781851862.250829&cid=C089VFRB8N9

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

edit: major ;)


</SdkOption>

<SdkOption name="profileSessionSampleRate" type="float" availableSince="8.7.0">

A number between `0` and `1`, controlling the percentage chance that the session will be profiled. (`0` represents 0%, `1` represents 100%.) The default is null (disabled).
Expand All @@ -370,7 +378,7 @@ Whether the UI profiling lifecycle is controlled manually or based on the trace

<SdkOption name="startProfilerOnAppStart" type="bool" defaultValue="false" availableSince="8.7.0">

A boolean value that determines whether the app start process will be profiled. When true, the startup process, including ContentProviders, Application, and first Activity creation, will be profiled. Note that <PlatformIdentifier name="profileSessionSampleRate" /> must be defined.
A boolean value that determines whether the app start process will be profiled. When true, the startup process, including ContentProviders, Application, and first Activity creation, will be profiled. Note that <PlatformIdentifier name="profileSessionSampleRate" /> must be defined. App start profiling is only supported by the <PlatformLink to="/profiling/legacy">legacy profiler</PlatformLink>, which runs on devices below Android 15 (API level 35). It has no effect with the ProfilingManager (Perfetto) backend used on API level 35 and higher.

- If profileLifecycle is set to `manual`: profiling is started automatically on startup and stopProfiler must be called manually whenever the app startup is deemed to be completed
- If profileLifecycle is set to `trace`: profiling is started automatically on startup, and will automatically be stopped when the root span that is associated with app startup ends
Expand Down
6 changes: 2 additions & 4 deletions docs/platforms/android/index.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,8 @@ Select which Sentry features you'd like to install in addition to Error Monitori

<OnboardingOption optionId="profiling">

<Alert level="warning">
Profiling uses the Android runtime's `tracer` under the hood to sample threads. There are known issues that this `tracer` can cause crashes in certain circumstances. See this <PlatformLink to="/profiling/troubleshooting#i-see-an-elevated-number-of-crashes-in-the-android-runtime-when-profiling-is-activated">troubleshooting</PlatformLink> entry for more information.
<Alert level="info">
On Android 15 (API level 35) and higher, profiling uses the Android <Link to="https://developer.android.com/reference/android/os/ProfilingManager">ProfilingManager</Link> to capture <Link to="https://perfetto.dev/">Perfetto</Link> traces. On older devices, the SDK automatically falls back to the <PlatformLink to="/profiling/legacy">legacy profiler</PlatformLink>.
</Alert>

</OnboardingOption>
Expand Down Expand Up @@ -128,8 +128,6 @@ Configuration is done via the application `AndroidManifest.xml`. Here's an examp
<meta-data android:name="io.sentry.traces.profiling.session-sample-rate" android:value="1.0" />
<!-- Set profiling lifecycle, can be `manual` (controlled through `Sentry.startProfiler()` and `Sentry.stopProfiler()`) or `trace` (automatically starts and stop a profile whenever a sampled trace starts and finishes) -->
<meta-data android:name="io.sentry.traces.profiling.lifecycle" android:value="trace" />
<!-- Enable profiling on app start -->
<meta-data android:name="io.sentry.traces.profiling.start-on-app-start" android:value="true" />
<!-- ___PRODUCT_OPTION_END___ profiling -->
<!-- ___PRODUCT_OPTION_START___ logs -->
<!-- Enable logs to be sent to Sentry -->
Expand Down
6 changes: 0 additions & 6 deletions docs/platforms/android/manual-setup/index.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -75,8 +75,6 @@ Configuration is done via the application `AndroidManifest.xml`. Here's an examp
<meta-data android:name="io.sentry.traces.profiling.session-sample-rate" android:value="1.0" />
<!-- Set profiling mode. For more info see https://docs.sentry.io/platforms/android/profiling/#enabling-ui-profiling -->
<meta-data android:name="io.sentry.traces.profiling.lifecycle" android:value="trace" />
<!-- Enable profiling on app start. The app start profile will be stopped automatically when the app start root span finishes -->
<meta-data android:name="io.sentry.traces.profiling.start-on-app-start" android:value="true" />

<!-- record session replays for 100% of errors and 10% of sessions -->
<meta-data android:name="io.sentry.session-replay.on-error-sample-rate" android:value="1.0" />
Expand Down Expand Up @@ -159,8 +157,6 @@ class MyApplication : Application() {
options.profileSessionSampleRate = 1.0
// set profiling mode. For more info see https://docs.sentry.io/platforms/android/profiling/#enabling-ui-profiling
options.profileLifecycle = ProfileLifecycle.TRACE
// enable profiling on app start. The app start profile will be stopped automatically when the app start root span finishes
options.isStartProfilerOnAppStart = true
// record session replays for 100% of errors and 10% of sessions
options.sessionReplay.sessionSampleRate = 0.1
options.sessionReplay.onErrorSampleRate = 1.0
Expand Down Expand Up @@ -218,8 +214,6 @@ public class MyApplication extends Application {
options.setProfileSessionSampleRate(1.0);
// set profiling mode. For more info see https://docs.sentry.io/platforms/android/profiling/#enabling-ui-profiling
options.setProfileLifecycle(ProfileLifecycle.TRACE);
// enable profiling on app start. The app start profile will be stopped automatically when the app start root span finishes
options.setStartProfilerOnAppStart(true);
// record session replays for 100% of errors and 10% of sessions
options.getSessionReplay().setSessionSampleRate(0.1);
options.getSessionReplay().setOnErrorSampleRate(1.0);
Expand Down
126 changes: 25 additions & 101 deletions docs/platforms/android/profiling/index.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -9,21 +9,22 @@ sidebar_section: features
<PlatformContent includePath="profiling/index/preface" />
<PlatformContent includePath="profiling/index/why-profiling" />

<Alert level="warning" title="Important">
Profiling uses the Android runtime's `tracer` under the hood to sample threads. There are known issues that this `tracer` can cause crashes in certain circumstances. See this <PlatformLink to="/profiling/troubleshooting#i-see-an-elevated-number-of-crashes-in-the-android-runtime-when-profiling-is-activated">troubleshooting</PlatformLink> entry for more information.
</Alert>
On Android 15 (API level 35) and higher, Sentry's Android UI Profiling is built on top of the Android <Link to="https://developer.android.com/reference/android/os/ProfilingManager">ProfilingManager APIs</Link>, which capture stack samples as <Link to="https://perfetto.dev/">Perfetto</Link> traces. This is the recommended way to profile your Android app.

<Alert level="info" title="Improved Profiling Coming Soon">
We're working on a more stable profiling solution based on the Android <Link to="https://developer.android.com/reference/android/os/ProfilingManager">ProfilingManager APIs (Perfetto)</Link>. Follow the <Link to="https://github.com/getsentry/sentry-java/discussions/5560">discussion on GitHub</Link> for updates.
<Alert level="info" title="Looking for the old profiler?">
On devices running below Android 15, the SDK automatically falls back to the legacy profiler, which samples threads using the Android runtime's `tracer`. That implementation, along with the transaction-based profiler, is now considered legacy. See <PlatformLink to="/profiling/legacy">Legacy Profiling</PlatformLink> for details, including how to disable it.
</Alert>

## Installation
## Prerequisites

UI Profiling is available starting in SDK version `8.7.0`. On **Android 15 (API level 35) or higher**, it uses the ProfilingManager (Perfetto) backend, available starting in SDK version `8.47.0`.

Android UI Profiling is available starting in SDK version `8.7.0`.
The transaction-based profiler is available on SDK versions `6.16.0` and higher through <PlatformLink to="/configuration/options/#transaction-based-profiling-options">its options</PlatformLink>.
On devices running below Android 15, the SDK automatically falls back to the <PlatformLink to="/profiling/legacy">legacy profiler</PlatformLink>. You can turn this fallback off, and disable profiling on those devices entirely, with the <PlatformLink to="/configuration/options/#enableLegacyProfiling">`enableLegacyProfiling`</PlatformLink> option.

## Enabling UI Profiling

To enable UI Profiling, set a `profileSessionSampleRate` and choose a profile lifecycle. The SDK automatically uses the ProfilingManager (Perfetto) backend on Android 15 (API level 35) and higher, and the legacy profiler on older devices.

UI 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.profiler.startProfiler` and `Sentry.profiler.stopProfiler`. You are entirely in the in control of when the profiler runs.
Expand All @@ -48,8 +49,6 @@ By default, some transactions will be created automatically for common operation
<!-- Enable UI profiling, adjust in production env. This is evaluated only once per session -->
<meta-data android:name="io.sentry.traces.profiling.session-sample-rate" android:value="1.0" />
<meta-data android:name="io.sentry.traces.profiling.lifecycle" android:value="trace" />
<!-- Enable profiling on app start. The app start profile will be stopped automatically when the app start root span finishes -->
<meta-data android:name="io.sentry.traces.profiling.start-on-app-start" android:value="true" />
</application>
```

Expand All @@ -72,8 +71,6 @@ public class MyApplication extends Application {
// Enable UI profiling, adjust in production env. This is evaluated only once per session
options.setProfileSessionSampleRate(1.0);
options.setProfileLifecycle(ProfileLifecycle.TRACE);
// Enable profiling on app start. The app start profile will be stopped automatically when the app start root span finishes
options.setStartProfilerOnAppStart(true);
});
}
}
Expand All @@ -97,8 +94,6 @@ class MyApplication : Application() {
// Enable UI profiling, adjust in production env. This is evaluated only once per session
options.profileSessionSampleRate = 1.0
options.profileLifecycle = ProfileLifecycle.TRACE
// Enable profiling on app start. The app start profile will be stopped automatically when the app start root span finishes
options.isStartProfilerOnAppStart = true
})
}
}
Expand All @@ -114,8 +109,6 @@ To enable manual profiling, set the lifecycle to `manual`. Manual profiling does
<!-- Enable UI profiling, adjust in production env. This is evaluated only once per session -->
<meta-data android:name="io.sentry.traces.profiling.session-sample-rate" android:value="1.0" />
<meta-data android:name="io.sentry.traces.profiling.lifecycle" android:value="manual" />
<!-- Enable profiling on app start. The app start profile has to be stopped through Sentry.stopProfiler() -->
<meta-data android:name="io.sentry.traces.profiling.start-on-app-start" android:value="true" />
</application>
```

Expand All @@ -137,13 +130,11 @@ public class MyApplication extends Application {
// Enable UI profiling, adjust in production env. This is evaluated only once per session
options.setProfileSessionSampleRate(1.0);
options.setProfileLifecycle(ProfileLifecycle.MANUAL);
// Enable profiling on app start. The app start profile has to be stopped through Sentry.stopProfiler()
options.setStartProfilerOnAppStart(true);
});
// Start profiling, if lifecycle is set to `manual` and startProfilerOnAppStart is set to `true`
// Start profiling
Sentry.startProfiler();
// Stop profiling, if lifecycle is set to `manual` and startProfilerOnAppStart is set to `true`.
// This call is optional. If you don't stop the profiler, it will keep profiling your application until the process exits.
// Stop profiling. This call is optional. If you don't stop the profiler, it will keep
// profiling your application until the process exits.
Sentry.stopProfiler();
}
}
Expand All @@ -166,95 +157,28 @@ class MyApplication : Application() {
// Enable UI profiling, adjust in production env. This is evaluated only once per session
options.profileSessionSampleRate = 1.0
options.profileLifecycle = ProfileLifecycle.MANUAL
// Enable profiling on app start. The app start profile has to be stopped through Sentry.stopProfiler()
options.isStartProfilerOnAppStart = true
})
// Start profiling, if lifecycle is set to `manual` and startProfilerOnAppStart is set to `true`
// Start profiling
Sentry.startProfiler()
// Stop profiling, if lifecycle is set to `manual` and startProfilerOnAppStart is set to `true`.
// This call is optional. If you don't stop the profiler, it will keep profiling your application until the process exits.
// Stop profiling. This call is optional. If you don't stop the profiler, it will keep
// profiling your application until the process exits.
Sentry.stopProfiler()
}
}
```

### Enabling Transaction-Based Profiling

<Alert>

This mode will eventually be deprecated, and it's recommended to upgrade to UI Profiling. The same behaviour, without the 30 seconds limitation, can be achieved with the <PlatformLink to="/profiling/#enabling-trace-lifecycle-ui-profiling">Trace Lifecycle UI Profiling</PlatformLink>. In order to upgrade to UI Profiling, you also need to remove the <PlatformLink to="/configuration/options/#transaction-based-profiling-options">transaction-based profiling options</PlatformLink> from your configuration.
Android transaction-based profiling is available starting in SDK version `6.16.0` and is supported on API level 22 and up.
App start profiling is available starting in SDK version `7.3.0`.

</Alert>

The transaction-based profiling only runs in tandem with performance transactions that were started either automatically or manually with `Sentry.startTransaction`, and stops automatically after 30 seconds (unless you manually stop it earlier). Naturally, this limitation makes it difficult to get full coverage of your app's execution.

```xml {filename:AndroidManifest.xml}
<application>
<meta-data android:name="io.sentry.dsn" android:value="___PUBLIC_DSN___" />
<!-- Enable tracing, needed for legacy profiling, adjust in production env -->
<meta-data android:name="io.sentry.traces.sample-rate" android:value="1.0" />
<!-- Enable transaction-based profiling, adjust in production env. This is relative to traces sample rate -->
<meta-data android:name="io.sentry.traces.profiling.sample-rate" android:value="1.0" />
<!-- Enable profiling on app start -->
<meta-data android:name="io.sentry.traces.profiling.enable-app-start" android:value="true" />
</application>
```

```java
import io.sentry.ProfileLifecycle;
import io.sentry.Sentry;
import io.sentry.android.core.SentryAndroid;

// App main Application class
public class MyApplication extends Application {
## Limitations

@Override
public void onCreate() {
super.onCreate();
SentryAndroid.init(
this,
options -> {
options.setDsn("___PUBLIC_DSN___");
// Enable tracing, needed for legacy profiling, adjust in production env
options.setTracesSampleRate(1.0);
// Enable transaction-based profiling, adjust in production env. This is relative to traces sample rate
options.setProfilesSampleRate(1.0);
// Enable profiling on app start
options.setEnableAppStartProfiling(true);
});
}
}
```

```kotlin
import io.sentry.ProfileLifecycle
import io.sentry.Sentry
import io.sentry.android.core.SentryAndroid

// App main Application class
class MyApplication : Application() {
override fun onCreate() {
super.onCreate()
SentryAndroid.init(
this,
{ options ->
options.dsn = "___PUBLIC_DSN___"
// Enable tracing, needed for profiling `trace` mode, adjust in production env
options.tracesSampleRate = 1.0
// Enable transaction-based profiling, adjust in production env. This is relative to traces sample rate
options.profilesSampleRate = 1.0
// Enable profiling on app start
options.isEnableAppStartProfiling = true
})
}
}
```
On Android 15 (API level 35) and higher, UI Profiling relies on the Android ProfilingManager, so the following limitations apply:

<Alert>
- **Older devices use the legacy profiler.** On devices below Android 15, the SDK automatically falls back to <PlatformLink to="/profiling/legacy">Legacy Profiling</PlatformLink>, which has different characteristics. You can disable this fallback with the <PlatformLink to="/configuration/options/#enableLegacyProfiling">`enableLegacyProfiling`</PlatformLink> option.
- **App start profiling is not supported.** The `startProfilerOnAppStart` option has no effect with the ProfilingManager (Perfetto) backend. App start profiling is only supported by the legacy profiler used on devices below Android 15. To learn more, see <PlatformLink to="/profiling/legacy">Legacy Profiling</PlatformLink>.
- **Profiling requests are rate limited and not guaranteed to be filled.** Apart from the SDK sampling rate, the Android Framework also restricts profiling, so not every request results in a profile. These limits are outside the SDK's control. To learn more, see the Android <Link to="https://developer.android.com/reference/android/os/ProfilingManager">ProfilingManager</Link> documentation.

The SDK won't run app start profiling the very first time the app runs, as the SDK won't have read the options by the time the profile should run.
The SDK will set the `isForNextAppStart` flag in `TransactionContext` if app start profiling is enabled.
<Alert level="info" title="Disabling Rate Limiting for Local Testing">
When testing locally, you can disable the Android Framework restrictions with the following shell command:

```bash
adb shell device_config put profiling_testing rate_limiter.disabled true
```
</Alert>
Loading
Loading