DevTools Profiler CLI
devtools_profiler_cli is the terminal and MCP front end for the pure-Dart
profiler package set.
Use it when you want to profile a Dart or Flutter VM command without opening the DevTools UI. It can capture the whole run, capture marked regions emitted by the target program, print readable terminal output, write JSON for automation, and serve the same capabilities to AI agents over stdio MCP.
For the full CLI guide, see the profiler README.
Install And Run
Install the CLI once:
dart pub global activate devtools_profiler_cli
devtools-profiler help
When testing an unpublished checkout, activate the local package instead:
dart pub global activate --source path packages/devtools_profiler_cli
devtools-profiler help
Profile the bundled fixture app:
devtools-profiler run \
--hide-sdk \
--hide-runtime-helpers \
--call-tree \
--method-table \
--cwd packages/devtools_profiler_core/test/fixtures/profiled_app \
-- dart run bin/profiled_app.dart
Profile your own app:
devtools-profiler run \
--cwd /path/to/app \
bin/main.dart
For full Dart or Flutter commands, put profiler options before the target
command. Use -- when the target command has its own options:
devtools-profiler run \
--json \
--duration 15s \
--hide-sdk \
--hide-runtime-helpers \
--call-tree \
--bottom-up \
--method-table \
--cwd /path/to/app \
-- dart run bin/main.dart
Bare Dart files are expanded to dart run <file>. Dart launches are held at
isolate exit long enough for final CPU and memory snapshots, so short scripts
can still produce a whole-session profile.
Profile the bundled terminal UI fixture:
devtools-profiler run \
--terminal \
--cwd packages/devtools_profiler_core/test/fixtures/profiled_app \
-- dart run bin/artisanal_widget_app.dart
Use --terminal when the target needs direct stdin, raw-mode input, mouse
tracking, or alternate-screen rendering. It cannot be combined with --json
because the target writes directly to the terminal. If you press Ctrl+C while
the CLI is running, the profiler writes the diagnostics captured so far before
printing the session summary.
Profile a Flutter test:
devtools-profiler run \
--json \
--duration 15s \
--hide-sdk \
--hide-runtime-helpers \
--call-tree \
--method-table \
--cwd /path/to/flutter/app \
-- flutter test test/widget_test.dart
Profile a Flutter app run:
devtools-profiler run \
--json \
--hide-sdk \
--hide-runtime-helpers \
--call-tree \
--method-table \
--cwd /path/to/flutter/app \
-- flutter run -d linux
--duration starts after the VM service is available. Flutter builds can take
longer than Dart scripts before a VM service URI is printed, so use
--vm-service-timeout 5m when profiling a cold build.
Attach to an already-running VM service:
devtools-profiler attach \
--json \
--duration 15s \
--hide-sdk \
--hide-runtime-helpers \
--call-tree \
--method-table \
--cwd /path/to/flutter/app \
http://127.0.0.1:8181/abcd/
Use attach mode when flutter run is already active and you want repeated
profiling windows without rebuilding. Start Flutter with a host VM-service port
when needed:
flutter run -d linux -t lib/main_relic_breach.dart --host-vmservice-port=0
The attach command clears the VM's existing CPU samples, captures the
whole-session VM service view for the requested duration, and does not stop the
target process. Explicit region markers normally require run mode because the
target must be launched with the profiler's DTD/session configuration.
What You Get Back
Each run or attach writes a session directory:
.dart_tool/devtools_profiler/sessions/<session-id>/
A session can contain:
overall: the whole process profile.regions: profiles for marked regions emitted bydevtools_region_profiler.- CPU summaries: top self frames, top total frames, top-down call trees, bottom-up call trees, and method tables.
- Memory summaries when memory capture was available.
- Warnings and artifact paths needed by later commands.
If the target app has no marked regions, the CLI still captures the whole session.
JSON responses include a cliCommand field for the command that can reproduce
the same analysis selection.
Read Existing Artifacts
Summarize a session:
devtools-profiler summarize \
--hide-sdk \
--hide-runtime-helpers \
--call-tree \
--method-table \
/path/to/session
Explain likely hotspots:
devtools-profiler explain \
--json \
--profile-id overall \
/path/to/session
Search for methods:
devtools-profiler search-methods \
--json \
--query Parser \
--sort total \
/path/to/session
Inspect one method:
devtools-profiler inspect \
--json \
--method Parser.parseFile \
--profile-id overall \
/path/to/session
Inspect memory classes:
devtools-profiler inspect-classes \
--json \
--class String \
--min-live-bytes 1048576 \
/path/to/session
Use --limit 0 for an unlimited class list. The command can read a session
directory, a region summary.json, or a raw memory_profile.json artifact.
Compare two sessions:
devtools-profiler compare \
--json \
--method-table \
/path/to/baseline-session \
/path/to/current-session
Analyze a series oldest to newest:
devtools-profiler trends \
--json \
/path/to/session-1 \
/path/to/session-2 \
/path/to/session-3
Important Flags
--jsonemits machine-readable JSON.--call-treeincludes the top-down call tree.--bottom-upincludes the bottom-up caller tree.--method-tableincludes DevTools-style caller and callee context.--hide-sdkhides Dart and Flutter SDK frames.--hide-runtime-helpershides profiler transport and runtime helper frames.--include-package <prefix>keeps only matching package prefixes.--exclude-package <prefix>removes matching package prefixes.--full-locationskeeps full source locations instead of compact labels.--frame-limit 0,--tree-depth 0,--tree-children 0, and--method-limit 0disable the corresponding output limits.--duration <duration>stops long-running targets after profiling for that duration. Examples:15s,2m,500ms.--vm-service-timeout <duration>controls startup wait time before the VM service is available. Examples:3m,300s.--terminalgives the launched process direct terminal access for TUI and alternate-screen apps. It cannot be combined with--json.--min-live-bytes <n>filters memory class rows forcompareandinspect-classes.--memory-class-limit <n>controls compared memory class rows forcompare.0means unlimited.
Commands that operate on one profile use --profile-id overall for the
whole-session profile or a generated region id for a marked region. Region names
are labels; region ids are printed in session summaries and exposed by MCP.
MCP Server
Start the local stdio MCP server:
devtools-profiler mcp
Example client configuration:
{
"command": "devtools-profiler",
"args": ["mcp"]
}
Agent-facing tools include:
profile_runprofile_attachprofile_summarizeprofile_read_artifactprofile_list_sessionsprofile_latest_sessionprofile_get_sessionprofile_list_regionsprofile_get_regionprofile_explain_hotspotsprofile_search_methodsprofile_inspect_methodprofile_inspect_classesprofile_compareprofile_compare_methodprofile_find_regressionsprofile_analyze_trends
Limits
- Attach mode captures a fixed whole-session VM-service window from an existing process, but explicit region markers normally require launch mode.
- Dart and Flutter VM-service commands only.
- Supported Flutter subcommands are
flutter runandflutter test. - Flutter release mode, browser profiling, AOT profiling, and
dart compile ...targets are not supported. - Flutter region markers require the target process to reach the profiler's local DTD URI. This works for host-side Flutter tests and desktop runs, but device runs may need additional networking.
- MCP transport is local stdio.
- If an MCP client does not inherit the Pub global executable path, configure
the client with the resolved
devtools-profilerexecutable path.
Libraries
- devtools_profiler_cli
- CLI and MCP entrypoints for the DevTools profiler backend.