Commands and Macros
This page covers how to automate common Perfetto UI tasks using commands, startup commands, and macros. For an overview of all ways to extend the UI, see Extending the UI.
Running commands
Commands are individual UI actions — pin a track, run a query, create a debug track. Run them through:
- Command palette:
Ctrl+Shift+P(Windows/Linux) orCmd+Shift+P(Mac) - Omnibox: Type
>to transform it into a command palette
Commands support fuzzy matching and autocomplete. See the Commands Automation Reference for the full list of stable commands.
Setting up startup commands
Startup commands run automatically every time you open any trace. Configure them in Settings > Startup Commands.
Startup commands are a JSON array of command objects:
[
{"id": "command.id", "args": ["arg1", "arg2"]}
]Commands execute in order. These affect only the UI display — the trace file is unchanged.
Pin important tracks automatically
[
{
"id": "dev.perfetto.PinTracksByRegex",
"args": [".*CPU [0-3].*"]
}
]Create debug tracks for custom metrics
[
{
"id": "dev.perfetto.AddDebugSliceTrack",
"args": [
"SELECT ts, thread.name, dur FROM thread_state JOIN thread USING(utid) WHERE state = 'R' AND dur > 1000000",
"Long Scheduling Delays (>1ms)"
]
}
]Use Perfetto SQL modules in debug tracks
When your query uses Perfetto modules, include the module first as a separate command:
[
{
"id": "dev.perfetto.RunQuery",
"args": ["include perfetto module android.screen_state"]
},
{
"id": "dev.perfetto.AddDebugSliceTrack",
"args": [
"SELECT ts, dur FROM android_screen_state WHERE simple_screen_state = 'on'",
"Screen On Events"
]
}
]Debug tracks visualize SQL query results on the timeline. The query must return:
ts(timestamp)- For slice tracks:
dur(duration) - For counter tracks:
value(the metric value) - Optional pivot column — results are grouped by unique values, each in its own track.
Command argument patterns:
- Without pivot:
AddDebugSliceTrack—[query, title] - With pivot:
AddDebugSliceTrackWithPivot—[query, pivot_column, title]
Standard analysis setup
This comprehensive startup configuration prepares the UI for system analysis:
[
{
"id": "dev.perfetto.CollapseTracksByRegex",
"args": [".*"]
},
{
"id": "dev.perfetto.PinTracksByRegex",
"args": [".*CPU \\d+$"]
},
{
"id": "dev.perfetto.ExpandTracksByRegex",
"args": [".*freq.*"]
},
{
"id": "dev.perfetto.AddDebugSliceTrackWithPivot",
"args": [
"SELECT ts, blocked_function as name, dur FROM thread_state WHERE state = 'D' AND blocked_function IS NOT NULL",
"name",
"Blocking Functions"
]
}
]Creating macros
Macros are named sequences of commands you trigger manually from the command palette. Configure them in Settings > Macros.
Macros are a JSON array of macro objects:
[
{
"id": "user.example.MacroName",
"name": "Display Name",
"run": [
{"id": "command.id", "args": ["arg1"]}
]
}
]- id: Unique identifier. Use reverse-domain naming (e.g.,
user.myteam.MemoryAnalysis). Keep IDs stable — they are used when referencing macros from startup commands. - name: Display name shown in the command palette. Can contain spaces.
- run: Commands to execute in sequence.
Run macros by typing >name in the command palette (e.g., >Memory Analysis).
Note (Migration): The macros format was changed from a dictionary to an array structure. If you had existing macros, they were automatically migrated to the new format. The migrated macros use IDs in the format
dev.perfetto.UserMacro.<old_name>.
Focus on a specific subsystem
This macro creates a workspace to isolate memory-related tracks:
[
{
"id": "user.example.MemoryAnalysis",
"name": "Memory Analysis",
"run": [
{
"id": "dev.perfetto.CreateWorkspace",
"args": ["Memory Analysis"]
},
{
"id": "dev.perfetto.CopyTracksToWorkspaceByRegexWithAncestors",
"args": [".*mem.*|.*rss.*", "Memory Analysis"]
},
{
"id": "dev.perfetto.SwitchWorkspace",
"args": ["Memory Analysis"]
},
{
"id": "dev.perfetto.AddDebugCounterTrackWithPivot",
"args": [
"SELECT ts, process.name as process, value FROM counter JOIN process_counter_track ON counter.track_id = process_counter_track.id JOIN process USING (upid) WHERE counter.name = 'mem.rss' AND value > 50000000",
"process",
"High Memory Processes (>50MB)"
]
}
]
}
]Investigate latency
This macro helps identify performance bottlenecks:
[
{
"id": "user.example.FindLatency",
"name": "Find Latency",
"run": [
{
"id": "dev.perfetto.PinTracksByRegex",
"args": [".*CPU.*"]
},
{
"id": "dev.perfetto.RunQueryAndShowTab",
"args": [
"SELECT thread.name, COUNT(*) as blocks, SUM(dur)/1000000 as total_ms FROM thread_state JOIN thread USING(utid) WHERE state = 'D' GROUP BY thread.name ORDER BY total_ms DESC LIMIT 10"
]
},
{
"id": "dev.perfetto.AddDebugSliceTrackWithPivot",
"args": [
"SELECT ts, 'blocked' as name, thread.name as thread_name, dur FROM thread_state JOIN thread USING (utid) WHERE state IN ('R', 'D+') AND dur > 5000000",
"thread_name",
"Long Waits (>5ms)"
]
}
]
}
]Combining with trace recording
When recording traces, specify startup commands that run when the trace opens:
./record_android_trace \
--app com.example.app \
--ui-startup-commands '[
{"id":"dev.perfetto.PinTracksByRegex","args":[".*CPU.*"]},
{"id":"dev.perfetto.AddDebugSliceTrackWithPivot","args":["SELECT ts, thread.name, dur FROM thread_state JOIN thread USING(utid) WHERE state = \"R\"","thread","Runnable Time"]}
]'Tips
Startup commands for always-needed views. If you always want certain tracks pinned, use startup commands.
Macros for specific investigations. Create macros for workflows you run occasionally (memory analysis, latency hunting, etc.).
Test interactively first. Use the command palette (
Ctrl/Cmd+Shift+P) to try commands before adding them to settings.Start clean. Begin command sequences with
CollapseTracksByRegexusing".*"to collapse all tracks first.Common regex patterns:
- Escape dots in package names:
"com\\.example\\.app" - Match any digit:
\\d+ - Match beginning/end:
^and$
- Escape dots in package names:
Debug tracks need good queries. Ensure SQL returns
tsand eitherdur(for slices) orvalue(for counters). For Android use cases, see Android Trace Analysis Cookbook.
Sharing with your team
If you want to share macros and SQL modules with others rather than maintaining them locally, use Extension Servers.
Common issues
- JSON syntax errors: Missing commas, trailing commas, or unescaped quotes.
- Invalid command IDs: Use autocomplete in the command palette to find valid IDs, or see the Commands Automation Reference.
- Wrong argument types: All arguments must be strings, even numbers.
- Wrong argument count: Each command expects a specific number of arguments.
- Module dependency errors: If your debug track query uses Perfetto modules
(e.g.,
android.screen_state), include the module first with aRunQuerycommand.
See also
- Extending the UI — Overview of all extension mechanisms
- Commands Automation Reference — Full reference for stable automation commands
- Extension Servers — Share macros and SQL modules with your team
- Perfetto UI Guide — General UI documentation
- Deep Linking — Opening traces with pre-configured commands via URLs