Profiling
Auto-capture heap dumps and Perfetto traces from Android apps using the platform's trigger-based profiling APIs.
Profiling captures a Perfetto system trace or a heap dump at a specific moment, so you can see exactly what the app was doing when it launched slowly or froze.
Profiling is Android only. It needs Android 16 (API level 36) or higher, and is a no-op on older versions.
Enable profiling
Profiling is off by default and turns on when WorkManager is a dependency of your app. Measure needs it because a trace or heap dump is often over 10 MB and has to upload durably in the background, and it leaves WorkManager out of the SDK so apps that don't profile don't carry the dependency.
Add the WorkManager dependency to your build.gradle.kts to switch profiling on. Without it, the collector never registers and nothing is captured.
Triggers
A trigger is an occasion when the operating system may capture a profile. Measure registers two.
Android 17 (API level 37) adds more triggers, such as out-of-memory, cold start, and excessive CPU usage. Capturing them needs building against compileSdk 37, so Measure registers only the two below.
App fully drawn (app_fully_drawn)
Fires once the app reports that its first meaningful content is on screen. This one isn't automatic: call Activity.reportFullyDrawn() yourself once the first screen is ready, including any data loaded asynchronously.
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
viewModel.loadHome()
}
// Call once the first meaningful content has finished rendering.
private fun onHomeContentReady() {
reportFullyDrawn()
}
}ANR (anr)
Captured when the app stops responding. The operating system detects ANRs itself, so there's nothing to add in your code.
The OS rate-limits each trigger, and Measure caps it at one profile per trigger type per hour, so a repeating problem won't flood the timeline with captures.
Sampling
Profiling is sampled on its own, separate from session sampling. The rate runs from 0 to 100 and defaults to 100, so every profile the OS produces is kept. Keep it high: the OS already rate-limits each trigger to once an hour, so a low client-side rate would collect almost nothing. Set it well above your other sampling rates.
How it works
Measure uses android.os.ProfilingManager, the trigger-based profiling API added in Android 16. The SDK registers the triggers above with the operating system, along with a callback for the results. The OS decides when to run a session, writes the result to a file, and hands it back, and Measure attaches that file to a profile event tagged with the trigger that produced it.
The artifacts are large, so a dedicated WorkManager worker uploads them in the background once the device has a network, apart from the normal event flow. After upload, you can download a result from the session timeline in the dashboard.
Further reading
Think this page can be better?
Open an issueScreen load time
Measure automatically traces how long Activities, Fragments, and ViewControllers take to draw their first frame, so you can find slow screens without any instrumentation.
Custom Events
Track app-specific events like user actions and feature usage, and view them on the session timeline.