Extension Servers

Extension servers are HTTP(S) endpoints that distribute shared macros, SQL modules, and proto descriptors to the Perfetto UI. They are the recommended way for teams and organizations to share reusable trace analysis workflows.

Why extension servers?

Without extension servers, sharing macros or SQL modules means copy-pasting JSON between teammates. This doesn't scale: definitions get out of date, new team members miss them, and there's no single source of truth. Extension servers solve this by letting you host extensions in one place and have everyone load them automatically.

Key properties

Extension servers are optional and never load-bearing. The Perfetto UI works fully without any servers configured — servers only provide optional enhancements.

All extensions are declarative and safe:

What extension servers provide

Macros

Macros loaded from extension servers appear in the command palette (Ctrl+Shift+P) alongside locally-defined macros. They show the server and module name as a source label so you can tell where each macro comes from.

See Commands and Macros for how macros work.

SQL modules

SQL modules become available for use in the query editor and in startup commands. Use them with:

INCLUDE PERFETTO MODULE <namespace>.<module_name>;

For example, if a server with namespace com.acme provides a module called com.acme.startup, you would write:

INCLUDE PERFETTO MODULE com.acme.startup;

See PerfettoSQL Getting Started for more on SQL modules.

Proto descriptors

Proto descriptors allow the UI to decode and display custom protobuf messages embedded in traces without needing the .proto files compiled into the UI. These are registered automatically when the extension server loads.

How extension servers work

Each extension server hosts a manifest that declares:

When the Perfetto UI starts, it fetches the manifest from each configured server, then loads extensions from the enabled modules. If a server is unreachable or returns errors, it is skipped — other servers and the rest of the UI are unaffected.

Modules

Extension servers organize content into modules. For example, a corporate server might offer:

When you add a server, the default module is selected automatically. Other modules are opt-in.

Namespacing

All macro IDs and SQL module names from a server must start with the server's namespace (e.g., com.acme.). This prevents naming conflicts when multiple extension servers are configured. The UI enforces this and rejects extensions that violate the convention.

Lifecycle

Extensions are loaded once at UI startup. If you change your extension server configuration (add/remove servers, change modules), you need to reload the page for changes to take effect.

Server types and authentication

Extension servers come in two types:

Each server type supports different authentication methods:

Server type Auth method When to use
GitHub None Public repositories
GitHub Personal Access Token Private repositories
HTTPS None Publicly accessible servers
HTTPS Basic Auth Username/password protected servers
HTTPS API Key Bearer token, X-API-Key, or custom header
HTTPS SSO Corporate SSO with cookie-based authentication

For most use cases (public GitHub repos + link sharing), no authentication is needed. See the protocol reference for the exact headers the UI sends for each auth type.

Creating extensions with GitHub

The easiest way to create an extension server is to use a GitHub repository — no custom server infrastructure needed.

Fork the template repository

Start by forking (or importing, for a private copy) the perfetto-test-extensions template repository on GitHub. This gives you a ready-made structure with a GitHub Action that automatically builds the endpoint files when you push.

Configure your server

Edit config.yaml to set your extension's name and namespace:

name: My Team Extensions namespace: com.example.myteam

The namespace must be unique to your organization and follows reverse-domain notation. All macro IDs and SQL module names must start with this namespace.

You can also configure which modules your server offers. By default, the template includes a default module. Add more if you want to organize extensions by team or topic:

name: My Team Extensions namespace: com.example.myteam modules: - id: default name: Default - id: android name: Android - id: chrome name: Chrome

Add SQL modules

Add .sql files under src/{module}/sql_modules/. The filename determines the SQL module name based on your namespace:

You can organize SQL files into subdirectories — each path component becomes a dot-separated part of the module name.

See PerfettoSQL Getting Started for how to write SQL modules.

Add macros

Add .yaml or .json files under src/{module}/macros/. Each macro has an id, a display name, and a run list of commands.

YAML example (src/default/macros/show_long_tasks.yaml):

id: com.example.myteam.ShowLongTasks name: Show Long Tasks run: - id: dev.perfetto.RunQueryAndShowTab args: - "SELECT * FROM slice WHERE dur > 50000000"

Equivalent JSON (src/default/macros/show_long_tasks.json):

{ "id": "com.example.myteam.ShowLongTasks", "name": "Show Long Tasks", "run": [ { "id": "dev.perfetto.RunQueryAndShowTab", "args": ["SELECT * FROM slice WHERE dur > 50000000"] } ] }

Macro IDs must start with your namespace (e.g., com.example.myteam.). See the Commands Automation Reference for the full list of available commands to use in macros.

Push and deploy

Push your changes to main. The included GitHub Action builds the generated endpoint files (manifest, modules/*/macros, etc.) and commits them automatically.

Adding an extension server in the Perfetto UI

Add a GitHub server

  1. Go to Settings (gear icon in the sidebar) and scroll to Extension Servers, or open the settings directly.
  2. Click Add Server and select GitHub.
  3. Enter the repository in owner/repo format (e.g., my-org/perfetto-extensions).
  4. Enter the branch or tag in the Ref field (e.g., main).
  5. The UI fetches the manifest and shows available modules. The default module is selected automatically; enable others as needed.
  6. Click Save and reload the page.

For private repositories, select Personal Access Token (PAT) under authentication:

  1. Go to GitHub personal access tokens and click Generate new token.
  2. Under Repository access, select Only select repositories and choose your extension repo.
  3. Under Permissions > Repository permissions, set Contents to Read-only.
  4. Generate the token and enter it in the Perfetto UI when adding the server.

Add an HTTPS server

  1. Click Add Server and select HTTPS.
  2. Enter the server URL (e.g., https://perfetto-ext.corp.example.com). The https:// prefix is added automatically if omitted.
  3. Select modules and configure authentication (see below).
  4. Click Save and reload the page.

Sharing extension servers

Click the Share button on any server in Settings to copy a shareable URL. When someone opens the link:

Secrets (PATs, passwords, API keys) are automatically stripped from shared URLs. Recipients enter their own credentials if the server requires authentication.

Managing servers

In the Extension Servers settings section, use the action buttons to:

Changes require a page reload to take effect.

Creating an HTTPS extension server

If you need more control than a GitHub repository provides — dynamic content, corporate SSO, or integration with internal systems — you can host an extension server on any HTTPS endpoint.

An extension server is a set of JSON endpoints. At minimum you need:

https://your-server.example.com/manifest → server metadata https://your-server.example.com/modules/default/macros → macros (optional) https://your-server.example.com/modules/default/sql_modules → SQL modules (optional)

You can serve these as static files (nginx, GCS, S3) or from a dynamic server (Flask, Express, etc.). The server must set CORS headers to allow the Perfetto UI to make cross-origin requests.

See the Extension Server Protocol Reference for the full endpoint specification, JSON schemas, CORS requirements, and examples including a minimal Python/Flask server.

Troubleshooting

If extensions fail to load, the UI shows an error dialog listing what went wrong. Errors are non-blocking — the UI works normally and extensions from other servers that loaded successfully remain available.

Below are the error messages you may see and how to fix them.

"Failed to fetch <url>: <error>"

The UI could not reach the server at all. This is usually a network or CORS issue.

"Fetch failed: <url> returned <status>"

The server was reachable but returned an HTTP error.

"Failed to parse JSON from <url>: <error>"

The server returned a response that isn't valid JSON.

"Invalid response from <url>: <error>"

The server returned valid JSON but it doesn't match the expected schema.

"Module '<name>' not found on server"

You have a module enabled in settings that the server's manifest doesn't list.

"Macro ID '<id>' must start with namespace '<ns>.'"

A macro's id field doesn't match the server's namespace.

"SQL module name '<name>' must start with namespace '<ns>.'"

Same as above, but for SQL modules. The module's name field must start with the server's namespace.

See also