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:
- Macros are sequences of UI commands — no JavaScript execution.
- SQL modules run inside trace processor's existing sandbox.
- Proto descriptors are binary type definitions (data only).
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:
- The server's name and namespace (e.g.,
com.acme) - Which features it supports (macros, SQL modules, proto descriptors)
- Which modules are available (named collections of extensions)
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:
default— General-purpose macros and SQL modulesandroid— Android-specific analysis workflowschrome— Chrome rendering performance tools
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:
- GitHub — Extensions hosted in a GitHub repository. The UI fetches files
directly from
raw.githubusercontent.com(public repos) or the GitHub API (private repos). This is the easiest option — no server infrastructure needed. - HTTPS — Extensions hosted on any HTTPS endpoint: a static file host (GCS, S3, nginx), a dynamic server (Flask, Express), or corporate infrastructure. The server must set CORS headers to allow the Perfetto UI to fetch from it.
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.myteamThe 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: ChromeAdd SQL modules
Add .sql files under src/{module}/sql_modules/. The filename determines the
SQL module name based on your namespace:
src/default/sql_modules/helpers.sqlbecomesINCLUDE PERFETTO MODULE com.example.myteam.helpers;src/default/sql_modules/foo/bar.sqlbecomesINCLUDE PERFETTO MODULE com.example.myteam.foo.bar;
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
- Go to Settings (gear icon in the sidebar) and scroll to Extension Servers, or open the settings directly.
- Click Add Server and select GitHub.
- Enter the repository in
owner/repoformat (e.g.,my-org/perfetto-extensions). - Enter the branch or tag in the Ref field (e.g.,
main). - The UI fetches the manifest and shows available modules. The
defaultmodule is selected automatically; enable others as needed. - Click Save and reload the page.
For private repositories, select Personal Access Token (PAT) under authentication:
- Go to GitHub personal access tokens and click Generate new token.
- Under Repository access, select Only select repositories and choose your extension repo.
- Under Permissions > Repository permissions, set Contents to Read-only.
- Generate the token and enter it in the Perfetto UI when adding the server.
Add an HTTPS server
- Click Add Server and select HTTPS.
- Enter the server URL (e.g.,
https://perfetto-ext.corp.example.com). Thehttps://prefix is added automatically if omitted. - Select modules and configure authentication (see below).
- 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:
- If they don't have the server configured, the Add Server dialog opens pre-populated with the shared configuration.
- If they already have the server, the Edit dialog opens with the shared modules merged in.
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:
- Toggle — Enable or disable a server without removing it.
- Edit — Change modules, authentication, or other settings.
- Share — Copy a shareable URL to the clipboard.
- Delete — Remove the server.
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.
- Check the URL. Open the URL in a new browser tab. If you can't reach it, the server may be down, the URL may be wrong, or you may need to be on a VPN.
- Check CORS headers. If the URL loads in a tab but the UI shows a fetch
error, the server likely isn't setting CORS headers. Open the browser console
(
F12) and look for "CORS policy" errors. See the CORS requirements for what headers to set. GitHub-hosted servers don't need CORS configuration. - Check for mixed content. The Perfetto UI is served over HTTPS, so it
cannot fetch from
http://URLs. Usehttps://for your server.
"Fetch failed: <url> returned <status>"
The server was reachable but returned an HTTP error.
- 401 or 403 — Authentication failed. For GitHub PATs, check that the token hasn't expired and has read access to the repository (Settings > Personal access tokens). For HTTPS servers with SSO, try logging into the server directly in a new tab to refresh your session, then reload the Perfetto UI.
- 404 — The endpoint doesn't exist. Check that the server implements the expected endpoint paths and that the repository/branch/path are correct.
"Failed to parse JSON from <url>: <error>"
The server returned a response that isn't valid JSON.
- Check that the endpoint returns
Content-Type: application/jsonand valid JSON. If using the GitHub template, make sure the GitHub Action has run successfully after your last push — check the Actions tab in your repository.
"Invalid response from <url>: <error>"
The server returned valid JSON but it doesn't match the expected schema.
- Compare your response against the expected format in the
protocol reference. Common
mistakes include missing required fields (
name,namespace,features,modulesin the manifest) or using the wrong field names.
"Module '<name>' not found on server"
You have a module enabled in settings that the server's manifest doesn't list.
- Edit the server in Settings and check which modules are enabled. If a module was renamed or removed from the server, deselect it and save.
"Macro ID '<id>' must start with namespace '<ns>.'"
A macro's id field doesn't match the server's namespace.
- If you maintain the server: update the macro ID to start with your namespace
(e.g., change
MyMacrotocom.acme.MyMacro). See namespace enforcement. - If you don't maintain the server: contact the server maintainer.
"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
- Extending the UI — Overview of all Perfetto UI extension mechanisms
- Extension Server Protocol Reference — Full specification for building custom servers
- Commands and Macros — How to create macros and startup commands