Repository navigation
Adopt Perfetto format for Android 17 profiling #6894
Copy link
Copy link
Open
Labels
Description
Perfetto is only available for continuous/UI profiling, not for the transaction profiles RN sends today. RN's experimental UI profiling, which would use Perfetto on API 35+, currently doesn't start on RN Android. So adopting Perfetto is a project, not a quick fix, and getsentry/relay#6517 is still needed either way.
What the code says
- sentry-android: on API 35+, continuous profiling uses
PerfettoContinuousProfiler(AndroidProfilingManager). Transaction-based profiling always uses the legacyDebugprofiler.AndroidOptionsInitializer.setupProfiler: "Transaction-based profiling always relies on the legacy Debug-based profiler… Perfetto profiling only supports continuous profiling." That matches sentry-java'sdevelop-docs/feature/profiling/perfetto.md: "Only continuous profiling is supported on the Perfetto path — transaction-based and app-start profiling are not." - Relay: Perfetto traces are only accepted as
profile_chunks (application/x-perfetto-trace, converted to Sample v2). The legacy transactionprofileitem has no Perfetto path. - RN: the default Android profile is a legacy transaction profile (Hermes
js_profileplus aDebugmethod trace). UI profiling exists only as_experiments.profilingOptions, which is forwarded to the native SDKs (RNSentryStart.configureAndroidProfiling). Nothing on the JS side uses it, so no Hermes/JS frames are captured, and Perfetto's native stack sampling wouldn't show JS functions either.
Tested on Android 17 (API 37 emulator), sample app, with profilingOptions passed natively through sentry.options.json. profilesSampleRate had to be removed natively, since sentry-android turns continuous profiling into a no-op when it's set.
- Native picks it up:
Continuous profiler is enabled true,PerfettoContinuousProfilingintegration registered, andDevice is API 35+. Skipping legacy app-start profiling — Perfetto ProfilingManager will be initialized after Sentry.init(). lifecycle: 'trace':Profiling lifecycle is set to TRACE but tracing is disabled. Profiling will not be started automatically.RN traces in JS, so native tracing is off and the profiler never starts.lifecycle: 'manual'+startOnAppStart: true: no Perfetto/ProfilingManageractivity, no chunks captured or sent within about 3 minutes.manualmode has no JS API. TheProfilingOptions.lifecycleJSDoc mentionsSentry.profiler.startProfiler/stopProfiler, but RN doesn't export them.
What adopting Perfetto would take
- Make RN UI profiling actually run on Android: drive the native continuous profiler from JS spans (
tracelifecycle doesn't work with JS tracing) and/or exposestartProfiler/stopProfiler. - Send Hermes samples as their own
profile_chunks linked byprofiler_id, so JS frames aren't lost, and confirm with the profiling team that the UI can combine JS and native chunks the way it combinesjs_profiletoday. - Account for
ProfilingManager's constraints: it's system rate-limited and its results arrive asynchronously. Fine for continuous sessions, not a drop-in for per-transaction start/stop.
Recommendation
- Keep Android 17 method traces rejected as profiling_invalid_sampled_profile: new ART header keys unsupported by android_trace_log relay#6517 as the fix for Android 17. It covers all shipped SDK versions and sentry-android's own transaction profiler.
- Treat Perfetto adoption as part of making RN UI profiling (with Hermes) work end to end on Android, which is also where native Android is heading.
- Small follow-ups found along the way: the
tracelifecycle doesn't work on RN Android, and the JSDoc references a non-existentSentry.profilerAPI.
Reactions are currently unavailable
Activity
linear-code commentedon Oct 15, 2026
RN-828
antonis commentedon Oct 15, 2026
Investigated what "adopt Perfetto on Android 17" would involve. Summary: Perfetto is only available for continuous/UI profiling, not for the transaction profiles RN sends today. RN's experimental UI profiling, which would use Perfetto on API 35+, currently doesn't start on RN Android. So adopting Perfetto is a project, not a quick fix, and getsentry/relay#6517 is still needed either way.
What the code says
PerfettoContinuousProfiler(AndroidProfilingManager). Transaction-based profiling always uses the legacyDebugprofiler.AndroidOptionsInitializer.setupProfiler: "Transaction-based profiling always relies on the legacy Debug-based profiler… Perfetto profiling only supports continuous profiling." That matches sentry-java'sdevelop-docs/feature/profiling/perfetto.md: "Only continuous profiling is supported on the Perfetto path — transaction-based and app-start profiling are not."profile_chunks (application/x-perfetto-trace, converted to Sample v2). The legacy transactionprofileitem has no Perfetto path.js_profileplus aDebugmethod trace). UI profiling exists only as_experiments.profilingOptions, which is forwarded to the native SDKs (RNSentryStart.configureAndroidProfiling). Nothing on the JS side uses it, so no Hermes/JS frames are captured, and Perfetto's native stack sampling wouldn't show JS functions either.Tested on Android 17 (API 37 emulator), sample app, with
profilingOptionspassed natively throughsentry.options.json.profilesSampleRatehad to be removed natively, since sentry-android turns continuous profiling into a no-op when it's set.Continuous profiler is enabled true,PerfettoContinuousProfilingintegration registered, andDevice is API 35+. Skipping legacy app-start profiling — Perfetto ProfilingManager will be initialized after Sentry.init().lifecycle: 'trace':Profiling lifecycle is set to TRACE but tracing is disabled. Profiling will not be started automatically.RN traces in JS, so native tracing is off and the profiler never starts.lifecycle: 'manual'+startOnAppStart: true: no Perfetto/ProfilingManageractivity, no chunks captured or sent within about 3 minutes.manualmode has no JS API. TheProfilingOptions.lifecycleJSDoc mentionsSentry.profiler.startProfiler/stopProfiler, but RN doesn't export them.What adopting Perfetto would take
tracelifecycle doesn't work with JS tracing) and/or exposestartProfiler/stopProfiler.profile_chunks linked byprofiler_id, so JS frames aren't lost, and confirm with the profiling team that the UI can combine JS and native chunks the way it combinesjs_profiletoday.ProfilingManager's constraints: it's system rate-limited and its results arrive asynchronously. Fine for continuous sessions, not a drop-in for per-transaction start/stop.Recommendation
tracelifecycle doesn't work on RN Android, and the JSDoc references a non-existentSentry.profilerAPI.alwx commentedon Oct 27, 2026
What's the expected outcome of this issue considering that getsentry/relay#6517 is fixed already? Should the description be updated? @antonis
antonis commentedon Oct 27, 2026
Makes @alwx 👍 Updated the description based on the comment above..