You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Adopt Perfetto format for Android 17 profiling #6894
Android 17 transaction profiles from the React Native sample app are dropped, while the same build is accepted on Android 16. The reported cause is that Android 17 ART method-trace headers include fields rejected by Relay's parser; skipping those fields makes the profile acceptable (workaround PR #6892, Relay issue #6517).
Proposal: adopt the Perfetto format for Android 17 profiling.
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
sentry-android: on API 35+, continuous profiling uses PerfettoContinuousProfiler (Android ProfilingManager). Transaction-based profiling always uses the legacy Debug profiler.AndroidOptionsInitializer.setupProfiler: "Transaction-based profiling always relies on the legacy Debug-based profiler… Perfetto profiling only supports continuous profiling." That matches sentry-java's develop-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 transaction profile item has no Perfetto path.
RN: the default Android profile is a legacy transaction profile (Hermes js_profile plus a Debug method 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, PerfettoContinuousProfiling integration registered, and Device 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/ProfilingManager activity, no chunks captured or sent within about 3 minutes.
manual mode has no JS API. The ProfilingOptions.lifecycle JSDoc mentions Sentry.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 (trace lifecycle doesn't work with JS tracing) and/or expose startProfiler/stopProfiler.
Send Hermes samples as their own profile_chunks linked by profiler_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 combines js_profile today.
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.
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.