# Commands Automation Reference

This page documents Perfetto UI's stable command surface specifically for
automation use cases. These commands have backwards compatibility guarantees and
can be safely used in automated workflows, startup configurations, macros, and
deep linking.

## Overview

While Perfetto UI uses commands internally for all user interactions, this
reference focuses exclusively on the subset of commands that are stable for
automation purposes. These stable automation commands are designed for:

- **Startup commands** - Automatically configure the UI when loading a trace
- **Macros** - Create reusable workflows for complex analysis tasks
- **Deep linking** - Share pre-configured views via URLs or postMessage

Commands outside this automation reference are internal implementation details
with no backwards compatibility guarantees and may change without warning.

## Backwards Compatibility Guarantees

For automation commands listed in this reference, Perfetto UI guarantees:

- **Stable command IDs** - The command identifier (e.g.,
  `dev.perfetto.RunQuery`) will not change
- **Stable required arguments** - Existing required parameters will continue to
  work with the same semantics
- **Consistent behavior** - Core functionality will be preserved across updates
- **Advance notice of changes** - Any breaking changes will be:
  - Published in the CHANGELOG
  - Announced at least 6 months before the change takes effect

Optional parameters may be added to commands without notice, but will not affect
existing usage.

## Command Reference

### Track Manipulation Commands

These commands control how tracks are displayed in the timeline view.

#### `dev.perfetto.PinTracksByRegex`

Pins tracks matching a regular expression pattern to the top of the timeline.

**Arguments:**

- `pattern` (string, required): Regular expression to match track names or paths
- `nameOrPath` (string, optional): Whether to match against track names ("name")
  or track paths ("path"). Defaults to "name"

**Track names vs paths:**

- Track name: `"RenderThread"`
- Track path: `"com.example.app > RenderThread"`

**Example:**

```json
{
  "id": "dev.perfetto.PinTracksByRegex",
  "args": [".*surfaceflinger.*"]
}
```

**Example with track path filtering:**

```json
{
  "id": "dev.perfetto.PinTracksByRegex",
  "args": [".*com\\.example\\.app.*RenderThread.*", "path"]
}
```

**Common patterns:**

- Pin CPU tracks: `".*CPU \\d+$"`
- Pin specific process: `".*com\\.example\\.app.*"`
- Pin multiple processes: `".*(system_server|surfaceflinger).*"`

---

#### `dev.perfetto.ExpandTracksByRegex`

Expands track groups matching a regular expression pattern.

**Arguments:**

- `pattern` (string, required): Regular expression to match track group names or
  paths
- `nameOrPath` (string, optional): Whether to match against track names ("name")
  or track paths ("path"). Defaults to "name"

**Track names vs paths:**

- Track name: `"RenderThread"`
- Track path: `"com.example.app > RenderThread"`

**Example:**

```json
{
  "id": "dev.perfetto.ExpandTracksByRegex",
  "args": [".*system_server.*"]
}
```

**Example with track path filtering:**

```json
{
  "id": "dev.perfetto.ExpandTracksByRegex",
  "args": [".*system_server.*RenderThread.*", "path"]
}
```

---

#### `dev.perfetto.CollapseTracksByRegex`

Collapses track groups matching a regular expression pattern.

**Arguments:**

- `pattern` (string, required): Regular expression to match track group names or
  paths
- `nameOrPath` (string, optional): Whether to match against track names ("name")
  or track paths ("path"). Defaults to "name"

**Track names vs paths:**

- Track name: `"RenderThread"`
- Track path: `"com.example.app > RenderThread"`

**Example:**

```json
{
  "id": "dev.perfetto.CollapseTracksByRegex",
  "args": ["CPU Scheduling"]
}
```

**Example with track path filtering:**

```json
{
  "id": "dev.perfetto.CollapseTracksByRegex",
  "args": [".*com\\.example\\.app.*", "path"]
}
```

**Tip:** Use `".*"` to collapse all tracks as a starting point for focused
analysis.

### Debug Track Commands

Create custom visualization tracks from SQL queries. Debug tracks are overlaid
on the timeline and update automatically when the view changes.

**Important:** If your queries use Perfetto modules (e.g., `android.screen_state`,
`android.memory.lmk`), you must first execute a `RunQuery` command with the module
include statement before creating the debug track. The module include must come
first in the command sequence.

#### `dev.perfetto.AddDebugSliceTrack`

Creates a slice track from a SQL query returning time intervals.

**Arguments:**

1. `query` (string, required): SQL query that must return:
   - `ts` (number): Timestamp in nanoseconds
   - `dur` (number): Duration in nanoseconds
   - `name` (string): Slice name to display
2. `title` (string, required): Display name for the track

**Example:**

```json
{
  "id": "dev.perfetto.AddDebugSliceTrack",
  "args": [
    "SELECT ts, dur, name FROM slice WHERE dur > 10000000 ORDER BY dur DESC LIMIT 100",
    "Long Slices (>10ms)"
  ]
}
```

---

#### `dev.perfetto.AddDebugSliceTrackWithPivot`

Creates multiple slice tracks grouped by a pivot column. Each unique value in
the pivot column gets its own track.

**Arguments:**

1. `query` (string, required): SQL query that must return:
   - `ts` (number): Timestamp in nanoseconds
   - `dur` (number): Duration in nanoseconds
   - `name` (string): Slice name to display
   - Additional column for pivoting
2. `pivotColumn` (string, required): Column name to group tracks by
3. `title` (string, required): Base title for the track group

**Example:**

```json
{
  "id": "dev.perfetto.AddDebugSliceTrackWithPivot",
  "args": [
    "SELECT ts, dur, name, IFNULL(category, '[NULL]') as category FROM slice WHERE dur > 1000000",
    "category",
    "Slices by Category"
  ]
}
```

**Note:** Use `IFNULL()` to handle NULL values in the pivot column, as NULLs
will cause the command to fail.

---

#### `dev.perfetto.AddDebugCounterTrack`

Creates a counter track from a SQL query returning time-series data.

**Arguments:**

1. `query` (string, required): SQL query that must return:
   - `ts` (number): Timestamp in nanoseconds
   - `value` (number): Counter value
2. `title` (string, required): Display name for the track

**Example:**

```json
{
  "id": "dev.perfetto.AddDebugCounterTrack",
  "args": ["SELECT ts, value FROM counter WHERE track_id = 42", "Memory Usage"]
}
```

---

#### `dev.perfetto.AddDebugCounterTrackWithPivot`

Creates multiple counter tracks grouped by a pivot column.

**Arguments:**

1. `query` (string, required): SQL query that must return:
   - `ts` (number): Timestamp in nanoseconds
   - `value` (number): Counter value
   - Additional column for pivoting
2. `pivotColumn` (string, required): Column name to group tracks by
3. `title` (string, required): Base title for the track group

**Example:**

```json
{
  "id": "dev.perfetto.AddDebugCounterTrackWithPivot",
  "args": [
    "SELECT ts, value, name FROM counter JOIN counter_track ON counter.track_id = counter_track.id",
    "name",
    "System Counters"
  ]
}
```

### Workspace Commands

Workspaces allow you to create custom views of your trace data by organizing
specific tracks together.

#### `dev.perfetto.CreateWorkspace`

Creates a new empty workspace.

**Arguments:**

- `title` (string, required): Name for the new workspace

**Example:**

```json
{
  "id": "dev.perfetto.CreateWorkspace",
  "args": ["Memory Analysis"]
}
```

---

#### `dev.perfetto.SwitchWorkspace`

Switches to an existing workspace by name.

**Arguments:**

- `title` (string, required): Name of the workspace to switch to

**Example:**

```json
{
  "id": "dev.perfetto.SwitchWorkspace",
  "args": ["Memory Analysis"]
}
```

**Note:** The workspace must exist before switching to it.

---

#### `dev.perfetto.CopyTracksToWorkspaceByRegex`

Copies tracks matching a pattern to a workspace.

**Arguments:**

1. `pattern` (string, required): Regular expression to match track names or
   paths
2. `workspaceTitle` (string, required): Target workspace name
3. `nameOrPath` (string, optional): Whether to match against track names
   ("name") or track paths ("path"). Defaults to "name"

**Track names vs paths:**

- Track name: `"RenderThread"`
- Track path: `"com.example.app > RenderThread"`

**Example:**

```json
{
  "id": "dev.perfetto.CopyTracksToWorkspaceByRegex",
  "args": ["(Expected|Actual) Timeline", "Frame Analysis"]
}
```

**Example with track path filtering:**

```json
{
  "id": "dev.perfetto.CopyTracksToWorkspaceByRegex",
  "args": [".*com\\.example\\.app.*RenderThread.*", "Frame Analysis", "path"]
}
```

---

#### `dev.perfetto.CopyTracksToWorkspaceByRegexWithAncestors`

Copies tracks matching a pattern to a workspace, including their parent track
groups for context.

**Arguments:**

1. `pattern` (string, required): Regular expression to match track names or
   paths
2. `workspaceTitle` (string, required): Target workspace name
3. `nameOrPath` (string, optional): Whether to match against track names
   ("name") or track paths ("path"). Defaults to "name"

**Track names vs paths:**

- Track name: `"RenderThread"`
- Track path: `"com.example.app > RenderThread"`

**Example:**

```json
{
  "id": "dev.perfetto.CopyTracksToWorkspaceByRegexWithAncestors",
  "args": ["RenderThread", "Rendering Analysis"]
}
```

**Example with track path filtering:**

```json
{
  "id": "dev.perfetto.CopyTracksToWorkspaceByRegexWithAncestors",
  "args": [
    ".*com\\.example\\.app.*RenderThread.*",
    "Rendering Analysis",
    "path"
  ]
}
```

### Query Commands

#### `dev.perfetto.RunQuery`

Executes a PerfettoSQL query without displaying results.

**Arguments:**

- `query` (string, required): PerfettoSQL query to execute

**Example:**

```json
{
  "id": "dev.perfetto.RunQuery",
  "args": [
    "CREATE PERFETTO FUNCTION my_func(x INT) RETURNS INT AS SELECT $x * 2"
  ]
}
```

#### `dev.perfetto.RunQueryAndShowTab`

Executes a PerfettoSQL query and displays results in a new query tab.

**Arguments:**

1. `query` (string, required): PerfettoSQL query to execute
2. `title` (string, optional): Title for the query tab

**Example:**

```json
{
  "id": "dev.perfetto.RunQueryAndShowTab",
  "args": ["SELECT ts, dur, name FROM slice LIMIT 50"]
}
```

**Example with tab title:**

```json
{
  "id": "dev.perfetto.RunQueryAndShowTab",
  "args": ["SELECT ts, dur, name FROM slice LIMIT 50", "Top 50 Slices"]
}
```

### Note Commands

#### `dev.perfetto.AddNoteAtTimestamp`

Add a note for a given timestamp in trace clock with specific text.

**Arguments:**

1. `timestamp` (string, required): Timestamp in trace clock (in nanoseconds)
2. `text` (string, required): Text for the note

**Example:**

```json
{
  "id": "dev.perfetto.AddNoteAtTimestamp",
  "args": [
    "1771711048774386000",
    "A specific event happened",
  ]
}
```

### Macro Commands

Macros are user-defined sequences of commands that execute in order. They
provide a way to automate complex, multi-step analysis workflows.

#### User-defined Macros

Macros can be defined through the UI settings (**Settings > Macros**). Each
macro has a unique ID that you define, which becomes the command ID used to
invoke it.

**Command Pattern:**

- `{macro.id}` - Executes the macro with the specified ID

**Arguments:**

None (macro commands and arguments are pre-configured)

**Example:**

```json
{
  "id": "user.myteam.MyAnalysisWorkflow",
  "args": []
}
```

**Notes:**

- Each macro contains a sequence of commands that execute in order
- Macro IDs should use reverse-domain style naming (e.g.,
  `user.myteam.MacroName`, `com.company.AnalysisWorkflow`)
- When used as startup commands, all commands within the macro must also be
  allowlisted
- Macros can include any stable automation command from this reference
- Failed commands within a macro are logged but don't stop execution of
  remaining commands

> **Note (Migration):** The macros format was changed from a dictionary to an
> array structure. Existing macros were automatically migrated and use IDs in
> the format `dev.perfetto.UserMacro.<old_name>`. New macros should use
> reverse-domain style IDs.

---

## Using Commands for Automation

These stable automation commands can be used in several contexts:

- **Startup Commands** - Automatically run when loading traces. See
  [Startup Commands](/docs/visualization/ui-automation.md#setting-up-startup-commands)
  in the UI automation guide.
- **Macros** - Named command sequences for on-demand execution. See
  [Macros](/docs/visualization/ui-automation.md#creating-macros) in the
  UI automation guide.
- **URL Deep Linking** - Embed commands in URLs or postMessage. See
  [Deep Linking](/docs/visualization/deep-linking-to-perfetto-ui.md#startup-commands)
  for URL patterns and postMessage integration.

For practical automation examples and recipes, see the
[UI Automation guide](/docs/visualization/ui-automation.md).

## Requesting New Stable Automation Commands

To request a command be added to the stable automation surface:

1. File an issue at https://github.com/google/perfetto/issues
2. Include:
   - The command ID you need stabilized
   - Your use case and why stability is important
   - Example usage showing how you plan to use it

Commands are prioritized based on:

- Frequency of use in automation scenarios
- Importance for common analysis workflows
- Feasibility of maintaining backwards compatibility

## See Also

- [UI Automation guide](/docs/visualization/ui-automation.md) - Practical
  recipes using these commands
- [Perfetto UI Guide](/docs/visualization/perfetto-ui.md) - General UI
  documentation including commands
- [Deep Linking](/docs/visualization/deep-linking-to-perfetto-ui.md) - Opening
  traces with pre-configured commands
