Measure logo

Profiling

Auto-capture heap dumps and Perfetto traces from Android apps using the platform's trigger-based profiling APIs.

Profiling is currently Android only and depends on the platform's trigger-based profiling APIs. It captures a Perfetto system trace or a heap dump when the system provides it.

Profiling is Android only. It works on Android 16 (API level 36) or higher, and is a no-op on older versions.

Enable profiling

Profiling only works when your app depends on WorkManager, which is required to upload traces and heap dumps (often over 10 MB) reliably in the background.

The SDK doesn't bundle WorkManager so apps that don't use profiling don't add an unnecessary dependency. You can add the WorkManager dependency to your build.gradle.kts to enable profiling.

Triggers

A trigger is an occasion when the operating system may capture a profile.

App fully drawn

App fully drawn fires once the app reports that its first meaningful content is on screen, on Android 16 (API level 36) and above. This requires you to call Activity.reportFullyDrawn() yourself once the first screen is ready.

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

Captured when the app stops responding, on Android 16 (API level 36) and above. The operating system detects ANRs itself.

Out of memory

Captures a Java heap dump when the app runs out of memory, on Android 17 (API level 37) and above. It only fires if any custom uncaught exception handler calls through to the default one.

Cold start

Captures a system trace and a stack sample from the start of a cold launch until the app reports it's fully drawn, or for 5 seconds. It works on Android 17 (API level 37) and above.

Excessive CPU usage

Captures a system trace when the system kills the app for using too much CPU, on Android 17 (API level 37) and above.

Sampling

The OS itself rate-limits each trigger at one profile per trigger type per hour.

On top of that you can apply a sampling rate to reduce the amount of profiles collected. However, given these APIs work only on Android 16 and above, the volume is generally very low so it is recommended to keep this sampling rate at 100%.

How it works

Profiling is built on 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 the SDK 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. Once uploaded, every profile shows on the Profiles page, where you can filter by profile trigger, open a profile in Perfetto, download it, or open its session replay.

Further reading

Think this page can be better?

Open an issue