Skip to content

Commit bc48e9b

Browse files
docs(android): Explain when ProfilingManager rejects profiling requests (#20129)
## DESCRIBE YOUR PR On Android 15+, UI Profiling runs on Android's `ProfilingManager`. Until now the docs only said requests are "rate limited and not guaranteed". This adds a **When Android Rejects Profiling Requests** section to the Android profiling page that covers: - How the SDK uses `ProfilingManager`: each chunk of up to 60s is a separate request, and `trace` mode sends a new request each time it restarts. - Why Android rejects requests: the per-app hourly/daily/weekly budget (`ERROR_FAILED_RATE_LIMIT_PROCESS`), the system-wide budget shared by all apps (`ERROR_FAILED_RATE_LIMIT_SYSTEM`), and a profiling session that's already running (`ERROR_FAILED_PROFILING_IN_PROGRESS`). - Why the app start and first screens get profiled more often than parts of the app users reach later in a session. - How to use the `manual` lifecycle (`Sentry.startProfiler()` / `Sentry.stopProfiler()`) to spend the limited budget on specific flows. I also moved the existing local-testing `adb` tip into this section and added a troubleshooting entry that points to it. The behavior matches `PerfettoContinuousProfiler` / `PerfettoProfiler` in sentry-java (60s `MAX_CHUNK_DURATION_MILLIS`, rate-limit error logging) and Android's [profiling limitations](https://developer.android.com/topic/performance/tracing/profiling-manager/will-my-profile-always-be-collected#how-rate-limiting-works) page. ## IS YOUR CHANGE URGENT? - [ ] Urgent deadline (GA date, etc.): YYYY-MM-DD - [ ] Other deadline: YYYY-MM-DD - [x] No deadline: Not urgent, can wait up to 1 week+ ## PRE-MERGE CHECKLIST - [ ] Checked Vercel preview for correctness, including links - [ ] PR was reviewed and approved by any necessary SMEs (subject matter experts) - [ ] PR was reviewed and approved by a member of the [Sentry docs team](https://github.com/orgs/getsentry/teams/docs) <!-- junior-request-attribution:start --> via **markus.hintersteiner**. <!-- junior-request-attribution:end --> <!-- junior-session-footer:start --> <!-- junior-conversation-id:slack%3AD0ANA6YA22F%3A1792582667.364859 --> -- [View Junior Session](https://junior-prod.sentry.dev/conversations/slack%3AD0ANA6YA22F%3A1792582667.364859) [[Sentry]](https://sentry.sentry.io/explore/conversations/slack%3AD0ANA6YA22F%3A1792582667.364859/?project=4510944073809921) <!-- junior-session-footer:end --> --------- Co-authored-by: sentry-junior[bot] <264270552+sentry-junior[bot]@users.noreply.github.com> Co-authored-by: Markus Hintersteiner <markus.hintersteiner@sentry.io>
1 parent 721e58a commit bc48e9b

2 files changed

Lines changed: 26 additions & 1 deletion

File tree

‎docs/platforms/android/profiling/index.mdx‎

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,21 @@ On Android 15 (API level 35) and higher, UI Profiling relies on the Android Prof
173173

174174
- **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.
175175
- **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>.
176-
- **Profiling requests are rate limited and not guaranteed to be fulfilled.** 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.
176+
- **Profiling requests are rate limited and not guaranteed to be fulfilled.** 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 [When Android Rejects Profiling Requests](#when-android-rejects-profiling-requests).
177+
178+
## When Android Rejects Profiling Requests
179+
180+
Whether a session gets profiled works like a funnel. First, the SDK decides whether to request profiling for the session, based on your `profileSessionSampleRate`. Then, the ProfilingManager applies its own limits and decides whether to record each request the SDK sends. When Android rejects a request, no profile is recorded for that time window, and the transactions and spans running during that window aren't linked to a profile.
181+
182+
The SDK records profiles in chunks of up to 60 seconds, and each chunk is a separate ProfilingManager request. In `trace` mode, the profiler also sends a new request every time it restarts after all sampled spans have finished.
183+
184+
Android rejects a profiling request in the following cases:
185+
186+
- **The app reached its profiling limit.** Each app gets a limited profiling budget per hour, per day, and per week. Once the app uses up any of these, Android rejects further requests until that period resets (`ERROR_FAILED_RATE_LIMIT_PROCESS`).
187+
- **The device reached its system-wide profiling limit.** All apps on a device share a global budget with the same hourly, daily, and weekly periods. Profiling by other apps can use up this budget, even if your app hasn't reached its own limit (`ERROR_FAILED_RATE_LIMIT_SYSTEM`).
188+
- **Profiling is already in progress.** Android rejects a request while another profiling session is running (`ERROR_FAILED_PROFILING_IN_PROGRESS`).
189+
190+
Android doesn't publish the exact budgets, and they may change between Android versions. To learn more, see the Android <Link to="https://developer.android.com/topic/performance/tracing/profiling-manager/will-my-profile-always-be-collected#how-rate-limiting-works">profiling limitations</Link> documentation. When <PlatformLink to="/configuration/options/#debug">debug mode</PlatformLink> is enabled, the SDK logs the error code of every rejected request.
177191

178192
<Alert level="info" title="Disabling Rate Limiting for Local Testing">
179193
When testing locally, you can disable the Android Framework restrictions with the following shell command:
@@ -182,3 +196,13 @@ On Android 15 (API level 35) and higher, UI Profiling relies on the Android Prof
182196
adb shell device_config put profiling_testing rate_limiter.disabled true
183197
```
184198
</Alert>
199+
200+
### Which Parts of Your App Get Profiled
201+
202+
Requests sent early in a rate-limit period are the most likely to be recorded, while later ones are more likely to be rejected. As a result, the app start and first screens (right after `Sentry.init()`) are usually profiled more often than parts of your app that users reach later in a session. In long sessions, later parts of your app may not be profiled at all once the app has used up its budget.
203+
204+
### Profiling Specific Parts of Your App
205+
206+
To get profiles for a specific flow, such as a checkout or a heavy screen, use the [`manual` lifecycle](#enabling-manual-lifecycle-ui-profiling). Call `Sentry.startProfiler()` when the flow starts and `Sentry.stopProfiler()` when it ends. This spends the limited budget on the code you want to investigate, instead of on everything that runs while a sampled span is active.
207+
208+
Keep manually profiled sections short, and always call `Sentry.stopProfiler()` when the flow is done. A profiler that keeps running sends a new request every 60 seconds, which uses up the app's budget quickly.

‎docs/platforms/android/profiling/troubleshooting/index.mdx‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,3 +25,4 @@ If you don't see any profiling data in [sentry.io](https://sentry.io), you can t
2525
- Ensure that the automatic instrumentation is sending performance data to Sentry by going to the **Performance** page in [sentry.io](https://sentry.io).
2626
- If the automatic instrumentation is not sending performance data, try using <PlatformLink to="/tracing/instrumentation/custom-instrumentation/">custom instrumentation</PlatformLink>.
2727
- Enable <PlatformLink to="/configuration/options/#debug">debug mode</PlatformLink> in the SDK and check the logs.
28+
- On Android 15 (API level 35) and higher, check the logs for `ERROR_FAILED_RATE_LIMIT_PROCESS` or `ERROR_FAILED_RATE_LIMIT_SYSTEM`. These mean Android's ProfilingManager rejected the profiling request. To learn more, see <PlatformLink to="/profiling/#when-android-rejects-profiling-requests">When Android Rejects Profiling Requests</PlatformLink>.

0 commit comments

Comments
 (0)