RFC-0005: Perfetto UI Server Extensions #3227
Replies: 7 comments
-
The name is very mysterious TBH. I'd call it something like Perfetto UI Server Extensions or similar. Also in the Decision part, i'd make it clear the server is optional for extra feature, and will never be load bearing.
Imho the name is a big confusing, not a big fan. provider is too generic.
This one I would call it "Site configured (or Installation configured)". The deal is that the Site points to a default server (or list of servers). but people creating a fork of perfetto can have their own dedault server ui.perfetto.dev is the Google-managed, and points to a default Google server (+ a second one for internal users)
I honestly couldn't make sense of this sentence About the endpoint: /teams has a semantic that is unnecessarily narrow. What if you don't have "teams" but want to break down things? Also note that regardless of how you call them, there is a fallacy in your naming scheme: you can't have both /teams (As a file) and /teams/foo. teams either is a directory or a file. they need to be named differently. My take is that there must be a central manifest like /manifest.json because at very least you need something like "a friendly human readable name". So I'd make it more like I'd honestly question whether we should have two different layers on the API level, rather than just /modules/default /modules/foo /modules/bar to keep everything flat and consistent
Why. This statement is confusing. You are suggesting that "perfetto" is special as name.
Are you going to mangle also the ID of the commands?
Wait what is an "extension" now? You never introduced this concept
** I claim the installation ones should always go first, and the setting ones after**
You forgot about the offline case. I question whether we should (in a V2) make these cached by the serviceworker or not. It might be worth it TBH.
It's not that easy. I'd move authentication to a different RFC as it's a bit of a beast.
I'd deal with versioning differently. You don't want to have "monolithic" versions oteherwise we'll increment stuff all the time. It needs to work like proto:
Let's move this to a different RFC |
Beta Was this translation helpful? Give feedback.
-
|
📝 RFC Document Updated View changes: Commit History |
Beta Was this translation helpful? Give feedback.
-
Naming & Clarity
Fixed: → "Perfetto UI Server Extensions"
Fixed: Added explicit statement that servers are optional and never load-bearing. UI works fully without them.
Fixed: "Provider" → "Extension Server" throughout. Added Terminology section defining Extension Server, Extension, and Module.
Fixed: → "Installation-configured"
Fixed: Rewrote to clearly explain UI deployments can package default servers but can't remotely provision into existing profiles. API Structure
Fixed:
Fixed: Flattened entirely. Now:
Fixed: {
"name": "Google Internal Extensions",
"modules": ["default", "android", "chrome"],
"csp_allow": ["https://symbolserver.corp.google.com"]
}
Fixed: → "default module" Load Order & Other
Fixed: Load order now: 1) Installation-configured servers first, 2) User-configured alphabetically
Fixed: Added note about service worker caching for V2 Auth & Versioning
Fixed: Created RFC-0006: Extension Server Authentication with full spec. RFC-0005 just references it.
Fixed: Proto-style versioning: Add fields freely, version individual features only when semantics change. No monolithic |
Beta Was this translation helpful? Give feedback.
-
|
📝 RFC Document Updated View changes: Commit History |
Beta Was this translation helpful? Give feedback.
-
|
📝 RFC Document Updated View changes: Commit History |
Beta Was this translation helpful? Give feedback.
-
|
📝 RFC Document Updated View changes: Commit History |
Beta Was this translation helpful? Give feedback.
-
|
📝 RFC Document Updated View changes: Commit History |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
📄 RFC Doc: 0005-provider-endpoint-system.md
Perfetto UI Server Extensions
Authors: @LalitMaganti
Status: Adopted
Summary
This RFC proposes a system for distributing Perfetto UI extensions (macros, SQL
modules, proto descriptors) and integrating with external services via standard
HTTP(S) endpoints. Extension servers are optional and never load-bearing - the
UI remains fully functional without them for local trace analysis.
Problem
Perfetto has several pain points around extensibility:
UI Extensions are hardcoded: The
is_internal_user_script_loader.tsfilecontains hardcoded URLs to internal Google resources. There's no standard way
for companies or individuals to distribute UI extensions.
No sharing mechanism: Users want to share custom macros and SQL modules
within their team without everyone manually copy-pasting JSON
(#3085).
Symbolization is complex: Requires magic environment variables, manual
symbol paths, etc. No unified way to query symbol servers.
No ACL story: We don't want to build and maintain our own
authentication/authorization system.
Local filesystem access problem: Browser-based UI cannot directly access
local filesystem for symbols, mappings, or extensions.
Terminology
Can be a static file host (GitHub, GCS, S3) or a dynamic server (corporate
infrastructure).
execution. Three types:
android,chrome,default). Allows users to selectively load relevant extension sets.Decision
Users can optionally configure HTTP(S) endpoints (extension servers) that serve
Perfetto UI extensions. The browser UI queries configured servers and aggregates
extensions from all enabled servers/modules.
Extension servers are optional and never load-bearing. The UI remains fully
functional without any servers configured - users can always perform local trace
analysis. Servers only provide optional enhancements like team-shared macros or
symbol resolution.
Scope
In Scope:
install are post-MVP followups)
Out of Scope (Separate RFCs):
browser integration, caching, mode selection, etc.)
traceconv, standalone scripts)trace_processor --httpdNote: Symbolization and deobfuscation endpoints are mentioned for
completeness and to establish the overall server architecture, but all
implementation details are deferred to a separate RFC.
Key Principles
corporate SSO), not custom Perfetto ACL
/manifest) providesserver metadata, supported features, and module list
descriptors), no JavaScript code execution
Architecture
Extension Server Configuration
Users configure extension servers in Settings → Extension Servers. Configuration
stored in localStorage using existing Perfetto settings system. Credentials
stored separately in localStorage.
Two ways to add servers in MVP:
internal server auto-added for Googlers)
Extension Server Store entries and URL-parameter-based one-click install remain
goals for a V1 followup (separate RFC covering catalog UX + distribution) and
are tracked in Phase 2 future work.
Installation-configured servers (like Google's internal server) are added on
first load with the
defaultmodule selected. Other modules remain opt-in viaSettings so users explicitly choose which content sets to enable.
Important: The Perfetto UI is a static client with no backend. Each UI
deployment (e.g., ui.perfetto.dev) can package default servers into the client
bundle, but cannot remotely provision servers or credentials into existing user
profiles. This is intentional - it follows from the "static client + no backend"
architecture. Organizations needing centralized provisioning must fork/deploy
their own UI bundle with the desired servers pre-configured.
Extension servers are configured with HTTPS URLs. For convenience, the UI also
supports shorthand aliases that resolve to standard HTTPS endpoints:
github://owner/repo/refresolves tohttps://raw.githubusercontent.com/owner/repo/refgs://bucket/pathresolves to GCS public HTTPS APIs3://bucket/pathresolves to S3 HTTPS APINote:
http://URLs are rejected - browsers don't allow mixed-content fetch,and silently upgrading can hide bugs if servers behave differently on HTTP vs
HTTPS.
Standard Endpoints
Extension servers implement these HTTP(S) endpoints:
Manifest Endpoint:
The
manifestendpoint returns server metadata, features, and module list:{ "name": "Google Internal Extensions", "namespace": "com.google", "features": ["macros", "sql_modules", "proto_descriptors"], "modules": ["default", "android", "chrome"] }Fields:
name(required): Human-readable server name shown in Settingsnamespace(required): Unique identifier for this server, following reversedomain notation (e.g.,
"com.google","dev.perfetto"). Used to preventnaming conflicts when multiple extension servers are configured:
a server with namespace
"com.google"must be named"com.google.startup","com.google.memory", etc.)"com.google.StartupAnalysis")the namespacing convention.
features(required): List of features this server provides. Valid values:"macros","sql_modules","proto_descriptors". The UI only fetchesendpoints for declared features - if a feature is not listed, the
corresponding endpoint is not queried.
modules(required): List of available modules. Use["default"]forsingle-module servers.
Extension Response Formats:
The extension endpoints return JSON with the following structures:
/modules/{module}/macros:{ "macros": [ { "id": "com.google.StartupAnalysis", "name": "Startup Analysis", "commands": [ {"id": "dev.perfetto.RunQuery", "args": ["SELECT 1"]} ] } ] }Note: The macro
idmust start with the server's namespace (e.g.,com.google.). Thenameis human-readable and shown in the command palette./modules/{module}/sql_modules:{ "sqlModules": [ {"name": "com.google.startup", "sql": "CREATE PERFETTO TABLE..."}, {"name": "com.google.memory", "sql": "CREATE PERFETTO FUNCTION..."} ] }Note: Each SQL module
namemust start with the server's namespace (e.g.,com.google.)./modules/{module}/proto_descriptors:{ "descriptors": [ "base64-encoded-descriptor-1", "base64-encoded-descriptor-2" ] }Request Strategy
The UI uses different request patterns for different endpoint types:
enabled server/module combinations and aggregates responses. Partial failures
are acceptable - failed servers are skipped and logged.
response ends the search).
Requests use fail-fast timeouts (5-30s depending on endpoint type), respect HTTP 429/503 rate limiting, and log failures to console.
What These Endpoints Provide
UI Extensions:
Macros (
/macros) - Named sequences of UI commands that users invoke viacommand palette. Example: "Android Startup Analysis" macro that pins specific
tracks and runs startup queries.
SQL Modules (
/sql_modules) - Reusable SQL code that creates tables,views, or functions. Example:
android.startupmodule with common startupanalysis queries.
Proto Descriptors (
/proto_descriptors) - Type definitions for customprotobuf messages in traces. Example: Android system_server proto definitions.
All extensions are declarative and execute locally - no trace data sent to
extension servers.
Symbolization & Deobfuscation:
/symbolize/*) - Convert addresses to function names,files, line numbers
/deobfuscate/*) - Convert obfuscated names to originalnames
Details for these endpoints deferred to separate RFC.
Module-Based Organization
Why modules exist:
In large organizations, different teams build different extensions:
Without modules, all extensions from a server would load for everyone, creating
noise. Modules let users choose which sets of extensions they want.
How modules work:
/manifestendpoint lists available modules and features:{"name": "...", "namespace": "...", "features": [...], "modules": [...]}defaultmodule (if available) is automatically selected when manifest isfetched. Other modules remain unselected so users can opt in explicitly.
/modules/android/macros,/modules/chrome/macros, etc.Implementation notes:
android-frameworks)permissions, GCS IAM, etc.)
Resource Naming and Conflicts
Namespace Enforcement
All resources from an extension server must be prefixed with the server's
namespace(from the manifest). The UI validates this constraint and rejectsresources that don't follow the convention:
{namespace}.(e.g.,com.google.StartupAnalysis){namespace}.(e.g.,com.google.startup)This prevents naming conflicts when multiple extension servers are configured.
Each organization controls their own namespace, ensuring resources from
different servers never collide.
Proto Descriptors
Proto descriptors are not namespaced since they define protobuf message types
which have their own package-based namespacing in the proto schema itself.
Extension Lifecycle
Extensions loaded ONCE on UI startup. Configuration changes require page
reload.
Load flow:
(installation-configured servers first, then user-configured servers
alphabetically)
Configuration changes:
apply changes"
Caching:
Cache-Control,ETag, etc.)This would allow extensions to work offline after initial load. Requires
separate design for cache invalidation and version management.
Failure handling:
initializes successfully with an empty extension set
Authentication
Note: Authentication implementation is covered in RFC-0006: Extension
Server Authentication. This section provides a high-level overview for context.
Extension servers support standard authentication mechanisms:
Authentication flow:
Full specification: See RFC-0006 for storage schemas, credential management
UI, OAuth flows, token refresh logic, and security considerations.
Examples
GitHub Static Hosting
Repo structure:
File:
manifest{ "name": "Acme Corp Extensions", "namespace": "com.acme", "features": ["macros", "sql_modules", "proto_descriptors"], "modules": ["default", "android", "chrome"] }File:
modules/default/macros{ "macros": [ { "id": "com.acme.StartupAnalysis", "name": "Startup Analysis", "commands": [{"id": "dev.perfetto.RunQuery", "args": ["SELECT 1"]}] } ] }File:
modules/default/sql_modules{ "sqlModules": [ {"name": "com.acme.startup", "sql": "CREATE PERFETTO TABLE..."} ] }Configuration:
Corporate Server
Configuration:
Security Considerations
Extension Safety
All extensions are declarative and safe - no code execution:
JavaScript plugins are NOT supported. Future executable plugins would require
separate RFC with sandboxing.
Server Integrity Expectations
Perfetto does not attempt to verify that server-hosted JSON or descriptor
payloads are trusted. Server operators are solely responsible for reviewing,
signing, or gating their own content before distribution to guard against
compromised repos or buckets. Each organization can apply its own signing or
review pipeline (e.g., proxy servers, checksum validation, internal CI) without
upstream coordination, and this RFC does not prescribe a canonical integrity
mechanism.
Data Sensitivity
For UI extensions: NO trace data sent to extension servers. Extensions
downloaded once and executed locally.
Consent model: Adding an extension server = implicit consent to load
extensions from it.
For symbolization (future RFC): Will send trace data (addresses, build IDs).
Future RFC will specify consent flow and warnings.
Credential Storage
leveraging the browser's same-origin protections for credentials is an
intentional design choice rather than a placeholder for future keychain work.
CORS Requirements
All HTTPS extension servers MUST set CORS headers:
CORS failure handling:
errors in the console)
Alternatives Considered
Custom
perfetto://URI SchemeRejected - Adds parsing complexity for minimal benefit. Standard HTTP(S)
URLs work fine.
Perfetto-Hosted Registry
Rejected - Single point of failure, doesn't solve private/corporate use
case. Decentralized model is better.
Build Custom ACL System
Hard Rejected - Huge implementation burden, users need another account.
Leverage existing systems (GitHub, GCS, corporate SSO).
Implementation
Phase 1: Core Extension Server Infrastructure
servers/modules)
Phase 2: UI Extensions
/manifest)is_internal_user_script_loader.tsdefaultmoduleselected)
Phase 2.5: Authentication (RFC-0006)
Phase 3: Post-MVP Enhancements
dedicated RFC)
?add_server=...)Phase 4: Local HTTP Accelerator (Future)
trace_processor --httpdto serve extension server endpointsPhase 5: Symbolization & Deobfuscation (Separate RFC)
Migration Strategy
is_internal_user_script_loader.tsassets with extensionservers happens centrally: hosted Perfetto deployments will update their
installation-configured server list and the UI automatically begins fetching
from the new endpoints on reload without user action.
ready, so the switch is transparent to users aside from the new Settings
surface.
to update the packaged server defaults before rolling the refreshed UI bundle.
Prerequisites
Design Decisions & Non-Goals
This section documents intentional scope boundaries and architectural choices to
prevent future confusion about what is explicitly out of scope.
SQL Module Safety:
resource limits and protections. No additional sandboxing is introduced by
this system. This matches how SQL modules work today.
Extension Versioning:
Extensions are always fetched fresh on reload. This matches how normal
websites work - users get the latest version on page load. Extension servers
are responsible for ensuring extensions remain compatible or coordinating
updates with users. Version pinning, rollback switches, or multi-version
compatibility matrices would require backend orchestration and are
intentionally excluded.
Proto Descriptor Validation:
parsing. Malformed descriptors are rejected and logged. No additional
validation layer is introduced.
Extension Update Notifications:
get latest extensions. Providers should ensure extensions are rolled out
safely, same as any distributed system. This is not different from how web
applications handle updates.
Resource Quotas:
The user explicitly adds servers, establishing an implicit trust relationship -
malicious or misconfigured servers are not an expected attack vector. In
practice, these limits are not expected to be reached. If performance issues
arise, limits can be added later.
Namespace Protection:
undefined behavior. Extension servers should use domain-specific names to
avoid conflicts with current or future built-in features.
Macro Validation:
fail at runtime when invoked. No upfront validation is performed. This matches
how ad-hoc macros work today - the macro simply fails to execute correctly if
it's malformed or incompatible with the UI version.
Cross-Server Dependencies:
servers. Loading order is deterministic but dependencies are not enforced. If
an extension relies on another extension being present, this is undefined
behavior and will fail at runtime. Users should configure extensions from a
single server if dependencies are required.
Extension Server Deployment Ownership:
each organization. The RFC does not prescribe SLAs, scaling rules, or shared
infrastructure so that internal and external deployments can evolve
independently.
Offline Distribution:
design. Teams that require offline readiness can fork or self-host the
Perfetto UI and manage their own distribution channel without upstream
protocol changes.
Telemetry Scope:
can add aggregate reporting once core plumbing is proven, but client behavior
today is limited to console logging.
defines event schemas, privacy review, and rollout expectations before any
data collection is enabled. Until that happens, console logging remains the
only supported observability surface.
💬 Discussion Guidelines:
Beta Was this translation helpful? Give feedback.
All reactions