perf-analyze)perf-analyze is a host-side tool designed to perform standalone, automated, and human-interactive performance analysis on Fuchsia traces. The tool acts as a CLI orchestrator that delegates trace processing to specialized analysis plugins.
query: Executes SQL queries to inspect and extract structured data from traces. Backed by Perfetto's Trace Processor.analyze: Executes specialized analysis plugins to identify performance anomalies (e.g., binder delays, jank, CPU starvation).visualize (Planned): Generates HTML reports, flamegraphs, SVGs, or deep-link trampoline URLs for the Perfetto UI.--format <json|markdown|text>: Specifies the output format (default: text).text: Unformatted tab-separated values (TSV), ideal for shell scripting.markdown: Formatted Markdown tables, ideal for doc insertion.json: Structured JSON, ideal for automated tool ingestion.query SubcommandThe query subcommand executes SQL queries against a trace file using Perfetto's Trace Processor.
--trace <path_or_url> (Required): File path to a local .fxt trace file or a URL to a remote trace.--sql <query_string>: Executes a single raw SQL query. Mutually exclusive with --batch.--batch <json_string_or_@filepath>: Executes a JSON array of queries in the format [{"name": "query_name", "sql": "select ..."}, ...]. Use @filepath to read the array from a local file. Mutually exclusive with --sql.fx perf-analyze query --help
Output:
usage: perf-analyze query [-h] --trace TRACE (--sql SQL | --batch BATCH) options: -h, --help show this help message and exit --trace TRACE Trace file path or URL --sql SQL SQL query to run --batch BATCH Batch JSON or @file
fx perf-analyze query \ --trace src/performance/perf-analyze/test-data/sample_fxt.fxt \ --sql "select count(*) as cnt from slice"
Output:
cnt 520
fx perf-analyze --format markdown query \ --trace src/performance/perf-analyze/test-data/sample_fxt.fxt \ --sql "select count(*) as cnt from slice"
Output:
| cnt | | --- | | 520 |
fx perf-analyze --format json query \ --trace src/performance/perf-analyze/test-data/sample_fxt.fxt \ --batch @src/performance/perf-analyze/test-data/sample_queries.json
Output:
[ { "name": "slice_count", "results": [ { "cnt": 520 } ] }, { "name": "process_count", "results": [ { "cnt": 2 } ] } ]
analyze SubcommandThe analyze subcommand runs specialized analysis plugins against a trace file to identify specific performance anomalies.
--trace <path_or_url> (Required): File path to a local .fxt trace file or a URL to a remote trace.--plugin <plugin_name> (Required): Name of the analysis plugin to execute (e.g., binder).--list-plugins: Lists all available analysis plugins.app-launch (App Launch Critical Path Breakdown)Decomposes the critical path of Android/Starnix application launches into contiguous chronological phase segments, intra-segment sub-operations, per-segment kernel thread states, and Fuchsia subsystem bottlenecks.
The plugin executes 5 diagnostic sections in order:
total_launch_ms (the launchingActivity slice) and displayed_ms (from ActivityTaskManager's START to the launch end, which matches logcat Displayed and AtmDisplayTime), and divides each launch into pre_start_ms (intent receipt to START, e.g. intent resolution or lock waits; 0 when the trace has no START marker, as for some hot launches), pre_fork_ms (START to Start proc), process_fork_ms (Zygote fork & specialization), attach_app_ms (ART post-fork init & attachApplication IPC), bind_app_ms (bindApplication), activity_lifecycle_ms (activityStart + activityResume), first_frame_ui_ms (first Choreographer#doFrame UI traversal), first_frame_render_ms (first RenderThread DrawFrame to TTID), and display_present_tail_ms (post-TTID Fuchsia Display::Client::CommitConfig). Warm and hot launches have no fork or bindApplication, so those columns are empty and pre_activity_ms covers the launch start to the first activityStart/activityResume. unattributed_ms is launch time that no segment covers because a milestone is missing, so the segments up to first_frame_render_ms plus unattributed_ms sum to total_launch_ms.init, draw, render, traversal, animation, and scenic). Nested slices (e.g. traversal > draw-VRI[...] > Record View#draw()) count only their self time, so no time on a thread is counted twice. Sub-stages on different threads can overlap in time. Reported as raw milliseconds (--scaling raw) or as each sub-stage's share of the attributed work, scaled to total_launch_ms (--scaling proportional).open_dex_ms, dlopen_ms, verify_class_ms, class_init_ms, get_resources_ms, inflate_ms, relayout_window_ms, dequeue_buffer_ms, shader_compile_ms, and queue_present_ms.running_cpu_ms (Running), runnable_starved_ms (R/R+/W), and sleeping_blocked_ms (S/D).BinderIoctl on Starnix), and Java monitor and native lock contention on the main thread and RenderThread. These count only outermost slices, clipped to the launch. It also reports system-wide Fxfs storage page-ins (page_in_chunk), time sysmem was busy (sysmem_busy_ms, not necessarily on the app's critical path), and Starnix SELinux hook overhead in the app process.--package <str>: Optional substring filter for package or process name.--limit <int>: Maximum number of rows returned per section (default: 20).--scaling <raw|proportional>: Report CUJ sub-stage durations as raw milliseconds (raw, default) or as each sub-stage's share of the attributed work, scaled to total_launch_ms (proportional).fx perf-analyze --format markdown analyze \ --trace out/e2e-testout/trace.fxt \ --plugin app-launch \ --package settings
binder (Starnix Binder Analysis)Analyzes Starnix binder delays, missed wakeups (scheduling delays), late-spawned wakers (SpawnLooper instant events), thread pool exhaustion (no_available_threads instant events), and process queue depth backlog (process_queue_depth counters).
[!TIP] Trace Category Recommendation: Including the
starnix:bindertrace category significantly improves the fidelity and depth of binder analysis. Withstarnix:binder, the plugin reconstructs full round-trip IPC transaction flows, driver queue wait times, thread pool exhaustion signals, and backlog counters. Ifstarnix:binderis not found in the trace, the plugin issues an explicit notification and falls back to best-effort heuristics usingbinder_ioctlslices andbinder:%thread naming patterns.
The plugin executes 5 diagnostic queries:
Runnable state duration) for binder threads exceeding the threshold.SpawnLooper thread-scoped instant events (dur = 0) and their enclosing syscall/ioctl parent slice context when the binder thread pool exhausts available threads.no_available_threads process-scoped instant events recorded when an incoming command cannot find an idle thread and queues to the process queue.process_queue_depth counter track peaks, averages, and sample counts per process.starnix:binderWhen the trace does not contain slices under the starnix:binder category:
starnix:binder.binder_ioctl slices and binder:% / binder_% thread names.--threshold-ms <float>: Threshold for scheduling delay and queue latency in milliseconds (default: 10.0). Does not filter instant events or queue depth counters.--complete-only: Only return complete transactions (default: False, includes incomplete transactions).fx perf-analyze --format markdown analyze \ --trace "https://ui.perfetto.dev/#!/?s=b3615b084da54e9a0742dd8f6280de355df4f513" \ --plugin binder \ --threshold-ms 15.0
cpu (CPU Utilization & Idle Power Diagnostics)Provides a multi-dimensional diagnostic view of system activity during an idle trace, identifying timer thrashing, excessive wakeups, per-core utilization and frequency scaling, async executor overhead, binder IPC chatter, and suspend/wake lease blockers.
The plugin executes 6 diagnostic queries in prioritized order:
Rate:CPU:N counters.--limit <int>: Maximum number of rows returned for ranked queries (default: 15).fx perf-analyze --format markdown analyze \ --trace src/performance/perf-analyze/test-data/sample_fxt.fxt \ --plugin cpu \ --limit 10
Unit tests are written using standard Python unittest. To build and run all unit tests, execute:
fx test perf_analyze_test app_launch_test binder_test result_formatter_test cpu_test plugins_test