Perfetto cheat sheet
Trace commands, a config that captures the things that matter, and the SQL queries that answer real questions about a trace.
A trace is the only way to see what actually happened. This sheet is the commands and queries worth memorising; the labs explain what to look for.
TL;DR#
adb shell perfettorecords on the device;adb pullretrieves the trace.- The categories that matter most:
sched,freq,idle,am,wm,gfx,view,binder_driver,input. trace_processorruns SQL over the trace, which turns "scroll around and squint" into a query.- The three tables you need:
slice,thread,process.
Mental model#
A trace is a database of intervals. Each slice is a row with a name, a start time and a duration, attached to a thread in a process. Everything else is a join away.
Where the analogy breaks#
The database is recorded at high frequency and is lossy at the edges: events outside the buffer window are gone, and some framework instrumentation only exists in debuggable builds.
The big picture#
Text description of this diagram
An annotated rendering of a Perfetto timeline. Rows are processes and threads; horizontal bars are slices; arrows are flow events connecting a cause to its effect across threads. The diagram marks the CPU scheduling track, the app's main and render threads, a binder transaction track, and the SurfaceFlinger compositor track, and explains what each visual element means.
Deep dive#
Record#
# quick on-device trace
adb shell perfetto -o /data/misc/perfetto-traces/trace.pftrace -t 10s \
sched freq idle am wm gfx view binder_driver input
adb pull /data/misc/perfetto-traces/trace.pftrace
# with explicit buffer sizes
adb shell perfetto -o /data/misc/perfetto-traces/trace.pftrace -t 20s -b 64mb \
sched freq idle am wm gfx view binder_driver resThere is also a text config file (--txt) for full control, and the on-device System Tracing app in
developer options.
Inspect#
Open the trace at ui.perfetto.dev, or use trace_processor for SQL:
trace_processor trace.pftrace
# or point the web UI at the file; the SQL tab uses the same engineThe SQL worth knowing#
-- longest slices overall
select s.name, s.dur / 1e6 as ms, t.name as thread, p.name as process
from slice s
join thread_track tt on s.track_id = tt.id
join thread t on tt.utid = t.utid
join process p using (upid)
order by s.dur desc
limit 20;
-- main-thread work during a window
select s.name, s.ts, s.dur / 1e6 as ms
from slice s
join thread_track tt on s.track_id = tt.id
join thread t on tt.utid = t.utid
where t.name = 'main'
order by s.ts;
-- frame timing, if FrameTimeline was recorded
select name, ts, dur / 1e6 as ms
from slice
where name like 'Choreographer#doFrame%' or name like 'DrawFrame%';
-- slice counts grouped by name: what dominates
select name, count(*) n, sum(dur) / 1e6 total_ms
from slice
group by name
order by total_ms desc
limit 30;Reading a trace#
- Find the process of interest and its main thread.
- Look at the frame markers; find the longest.
- Walk up the slice stack inside that frame to the widest child.
- Follow flow arrows across threads to see what the work waited on.
- Check the CPU scheduling row: was the thread runnable but not running?
How it evolved#
Curiosity corner#
- A trace can show a thread was runnable but starved. That is a scheduling problem, not a code problem, and it looks identical to slowness if you only read the slice names.
- Flow arrows are the most underused feature in the UI. They connect a cause on one thread to its effect on another.
Try it#
Record the trace described above and find the longest slice on the main thread. That slice is where your next performance fix lives.
Check yourself#
Check yourself
What does an API level identify?
Sources#
Sources
Every version number, API level, class name and date on this page is traced to one of these. Pages are re-verified against them; last_verified above says when.
- docsPerfetto documentationperfetto.devaccessed 2026-10-27↩
- docsAndroid tracing with Perfettoperfetto.devaccessed 2026-10-27↩
- docsTrace Processorperfetto.devaccessed 2026-10-27↩
- docsPerfetto SQL tablesperfetto.devaccessed 2026-10-27↩
- docsOverview of system tracingdeveloper.android.comaccessed 2026-10-27↩