Technical review — 2026-10-13: This article was written in 2015. Its event-timeline concepts remain useful, while the Eclipse / Device Monitor entry points are obsolete. Historical script options below are checked against AOSP
android-5.0.0_r1. The added Perfetto commands target Android 11 / API 30 and later, with older-system differences noted separately. Continue with the Android Perfetto series catalog.
| Old workflow | Current counterpart |
|---|---|
| Systrace button in Eclipse / Device Monitor | On-device System Tracing from Android 9 / API 28, or capture through ADB |
systrace.py calls atrace and produces HTML |
Perfetto records a binary trace, with events selected by categories or a config file |
| Open the old HTML directly in a browser | Import the trace into Perfetto UI, or analyze it with Trace Processor SQL |
| Assume user builds cannot trace | User builds can record system traces; available data depends on the OS, data source, app configuration, and vendor policy |
This is the first article in the Android Performance Optimization Tools series. This series mainly introduces the tools used during the Android performance optimization process, how to use these tools to discover problems, and how to solve them. In terms of performance optimization, Android provides many performance tools for everyone to use. Following our consistent “discover problem - solve problem” thinking, discovering the problem is the most important part. Trying to solve a problem without first identifying it properly often leads to twice the effort for half the result.
In this article, we’ll start with a brief introduction to the Systrace tool.
Introduction to Systrace
Systrace arrived with Android 4.1 / SDK Tools R20 as a system-event tracing and visualization tool. It places enabled CPU scheduling, SurfaceFlinger, WindowManager, View, and other events on a shared timeline. It does not automatically sample every Java method or provide complete call stacks. See the original SDK Tools R20 announcement.
The historical workflow has three parts:
- Kernel events: These depend on enabled ftrace support and accessible kernel events. Scheduling, I/O, frequency, and other categories must be checked on the device.
- Userspace annotations and collection: System components emit ATrace markers, while
atraceconfigures categories and reads tracing data. Apps can add their own sections withandroid.os.Trace.beginSection()/endSection(); these public APIs were added in Android 4.3 / API 18, not Android 4.1. - Host-side reporting: The old
systrace.pyinvokes atrace over ADB, processes the data, and builds an HTML report with a viewer. Existing system events can be captured without changing app code; custom business-operation sections require instrumentation.
Perfetto supports additional data sources, so describing all of it as an ftrace wrapper would be incomplete. It still reads android.os.Trace markers. See the Trace API and Perfetto ATrace documentation.
Simple Usage of Systrace
The basic sequence is the same with either tool: prepare the page, start recording, reproduce the interaction, stop and save the trace, then confirm that the required events and time range were captured. A successfully created file alone does not establish that it contains the problem.
Historical GUI Entry Points — Obsolete
These locations are retained for reading older instructions. Android Device Monitor was deprecated in Android Studio 3.1 and removed in 3.2.
- Eclipse: Open the DDMS perspective, select a device in Devices, then use its Systrace button.
- Early Android Studio: Open Tools → Android → Monitor, select a device, and click Systrace.
- Standalone Device Monitor: Run
monitorfrom an old SDK tools directory and follow the same process. These buttons are not part of current Android Studio.
Today, open System Tracing in the device’s Developer options. Android 9 produces Systrace .ctrace files; Android 10 / API 29 and later produce Perfetto traces. Select the needed categories, record the interaction, stop, and retrieve the file.
Command Line: Perfetto
I recommend the command line: set it up once, and repeating a capture is much easier. This example assumes an Android 11 / API 30 or later device connected and authorized through ADB. Inspect available categories before choosing what to record:
1 | adb shell atrace --list_categories |
Perform the interaction during the 10-second recording, then pull the file after the command finishes. Adjust unsupported categories using the device’s list. -b 64mb configures the Perfetto ring buffer; it is not the old script’s KB value or a guarantee of the final file size. With multiple devices connected, use the same adb -s DEVICE_SERIAL selection for every command.
This is Perfetto’s simple mode, primarily configuring ftrace / atrace. It does not enable every data source; FrameTimeline, for example, requires its own data-source configuration. See the Perfetto CLI reference.
Perfetto was included in Android 9, but some Android 9 / 10 devices require tracing services to be enabled first, and Android 9 has different file-pull permission constraints. Consult the Android capture compatibility notes before applying this entire workflow to an older device.
App Custom Events
To include app ATrace markers, specify the app process name. The default main process usually matches the package name; check actual names for a multiprocess app. For example:
1 | adb shell perfetto -t 10s -b 64mb -a com.example.app \ |
-a enables selected app markers; it does not insert method instrumentation. The app must already contain Trace calls in framework, library, or business code and satisfy that OS version’s tracing requirements. For example, on Android 10 / 11 user builds, an app generally needs to be debuggable or declare <profileable android:shell="true" /> inside <application>, an option introduced in API 29. Prefer an appropriate profileable release build for timing comparisons so debug overhead is not mistaken for production behavior. See the profileable version and access rules.
Synchronous beginSection() / endSection() calls must be paired on the same thread and correctly nested; use try/finally to ensure the end is recorded. A section’s elapsed duration can include waiting and preemption, so it is not necessarily CPU execution time.
Historical Systrace Commands — Android 5.0 Source Version
The following options are checked against systrace.py at AOSP android-5.0.0_r1. It uses Python 2 syntax and adjacent report resources; the script alone is insufficient. Historical SDK packages placed it under locations such as platform-tools/systrace, but do not assume that directory exists in a current installation.
From a matching old tool directory containing the script and its assets:
1 | python2 systrace.py --list-categories |
Python 2 describes the historical environment here; do not restore an obsolete interpreter just to capture a current device. Existing HTML traces can be imported directly into Perfetto UI rather than relying on the old embedded viewer to work in a current Chrome release. See supported external trace formats.
These options belong to that script version, not to perfetto:
| Option | Purpose |
|---|---|
-h, --help |
Display script help |
-o FILE |
Write HTML; the default filename is trace.html |
-t N, --time=N |
Record for N seconds; this Android 5.0 combination inherits atrace’s five-second default when omitted; check help for other versions |
-b N, --buf-size=N |
Pass a KB buffer setting to atrace, corresponding to per-CPU kernel buffers; CPU count, events, and compression also affect report size |
-k FUNCTIONS, --ktrace=FUNCTIONS |
Select comma-separated kernel functions, subject to kernel support and permissions |
-l, --list-categories |
List categories available on the connected device |
-a NAMES, --app=NAMES |
Enable markers for comma-separated app process names |
--from-file=FILE |
Build a report from an existing compressed trace, not from an arbitrary renamed file |
--link-assets, --asset-dir=DIR |
Control the historical report’s CSS / JavaScript resource references and directory |
-e SERIAL, --serial=SERIAL |
Select an ADB device |
See the Linux ftrace documentation for per-CPU buffers, and Android 5.0 atrace.cpp for the five-second default.
Common categories include gfx, view, wm, am, input, sched, freq, and idle. The original list also included membus, load, sync, and workq; these are not available on every version. The historical dalvik category name does not establish that a device runs Dalvik rather than ART. Query the actual category list before copying a long set of tags.
Saving Historical Aliases
If you maintain a matching legacy environment, Bash / Zsh aliases can shorten the commands. Replace the example path before loading this configuration:
1 | SYSTRACE_SCRIPT='/path/to/legacy/systrace.py' |
There must be no spaces around = in an alias assignment, and the quotes must be straight shell quotes. The categories still need device support. Use .html for an identifiable output name; changing the extension to .Trace does not change the format. You don’t need to memorize every option now. Start by capturing the events you need; the options will become familiar as you use them to analyze traces.
About Me && Blog
Below is my personal intro and related links. I look forward to exchanging ideas with fellow professionals. “When three walk together, one can always be my teacher!”
- Blogger Intro
- Blog Content Navigation: A guide for my blog content.
- Curated Excellent Blog Articles - Android Performance Optimization Must-Knows
- Android Performance Optimization Knowledge Planet: The paid community stopped operating in 2026 and no longer accepts new members; this link preserves its history.
One walks faster alone, but a group walks further together.
