xcprof Reference (Structured xctrace Capture & Analysis)
Complete reference for xcprof, the Axiom-bundled CLI that captures Instruments traces and turns them into structured, token-lean reports for coding harnesses. It replaces the old grep-the-XML profiling pipeline: it records with bounded, gated xctrace invocations, resolves xctrace's id/ref back-references that defeat grep, reports an honest per-family support matrix (never "no findings" when it means "couldn't measure"), and attributes CPU work to user code instead of burying it under dyld/libsystem. Every subcommand emits a compact JSON object with a tool/version envelope, and exit codes drive pass/fail in scripts.
When to Use This Reference
Use this reference when:
- Looking up
xcprof doctor/record/analyze/comparesubcommand flags - Choosing a recording preset (
cpu/memory/network/energy/full/full-ios) or recording a single--template/--instrument - Understanding the security gates — why
--launchneeds--allow-launch,--all-processesneeds--allow-all-processes, and how--max-durationandXCPROF_TRACE_ROOTbound a capture - Interpreting an exit code (0 ok / 2 environment-or-usage error / 3 regression found via
compare --fail-on-regression/ 8 output-write error) - Reading the support matrix (
available/partial/not_exportable/not_present) and understanding why memory/energy readnot_exportable - Symbolicating raw-address frames from a stripped/release build with
--dsym(explicit path or UUID auto-discovery) - Re-scoping CPU analysis to a hang window with
--start-ms/--end-mswithout re-recording - Previewing the exact
xctracecommand arecordwould run (--dry-run)
Example Prompts
- "How do I record a CPU trace and analyze it in one workflow?"
- "How do I profile my app without letting the tool launch arbitrary processes?"
- "Why does my analyze report show memory as
not_exportable?" - "How do I symbolicate a release build's stack frames in a trace?"
- "How do I re-analyze just the 2.0–2.5s window where I saw a hang?"
- "Which processes used the network in my trace, and how many bytes?"
- "What does
xcprof doctorcheck?" - "Why did
xcprof recordexit non-zero but still save a trace?" - "Which preset records leaks and allocations?"
- "Can I run xcprof from Cursor or Codex instead of Claude Code?"
What's Covered
- Invocation –
xcprofis on PATH as a bare command (pluginbin/is auto-resolved); runxcprof <subcommand>. MCP clients (Codex, Cursor, …) get the same surface via the wrapper toolsaxiom_xcprof_doctor/axiom_xcprof_analyze/axiom_xcprof_compare/axiom_xcprof_record(CLI flags map to camelCase params, a deliberate subset — see the skill for the full mapping) doctorsubcommand – verifiesxcrun xctraceand counts available instruments/devices;--humanfor prose. Exit0ready,2if xctrace is missingrecordsubcommand – captures a.traceand reports the saved path so you can hand it straight toanalyze. Picks instruments by--preset(defaultcpu), or--template <name>/ repeated--instrument <name>(one source only). A target is required — exactly one of--attach <pid|name>,--all-processes, or-- <cmd>(launch, after a literal--). Emits compact JSON (savedtrace, resolvedinstruments, effectivetime_limit,target_mode, and the fullcommandecho for transparency);--humanfor text;--dry-runpreviews without spawning- Recording presets – six verified preset → instrument maps (see table below).
cpuuses CPU Profiler (schemacpu-profile) andnetworkuses Network Connections (schemanetwork-connection-stat) — the two familiesanalyzeparses, so both round-trip from record → analyze; the instrument names are verified against real exports, not guessed - Security gates – bounded by default (
--max-duration, default 60s; an unset--time-limitadopts it, so a capture is never unbounded),--allow-launchbefore-- <cmd>will execute anything,--allow-all-processesbefore system-wide capture, and anXCPROF_TRACE_ROOToutput sandbox (--outputmust resolve under it or cwd unless--allow-external-output).--no-promptis needed for non-interactive use analyzesubcommand – exports the TOC, thecpu-profiletable, and thenetwork-connection-stattable (when present), resolves back-references into full backtraces, and reports the summary, support matrix, CPU hot frames (inclusive + self as % of total cycles plus an approximate ms), an approximate main-thread stall signal, top user-code frames, and a network section (socket connections aggregated by process: protocol, remote, bytes in/out). Flags:--json/--both,--start-ms/--end-ms(hang-window scoping),--hang-threshold-ms,--user-binary <names>,--dsym <path>,--opencomparesubcommand – diffs two traces (xcprof compare <baseline> <current>) into per-function CPU-share deltas (incl_pct_delta,self_pct_delta,incl_ms_delta), classifies each framechanged/new/gone, and flags any frame at or above--threshold-pct(default 5) as a regression.--fail-on-regressionexits3for CI gating;--dsymsymbolicates both traces;--human/--bothfor output. Assumes a like-for-like workload. See the trace-comparison workflow and the/axiom:compare-tracescommand- Honest support matrix – per family,
available(parsed, results present),partial(schema present but nothing parsed),not_exportable(the instrument's data isn't surfaced byxctrace export— memory's Allocations/Leaks live in the trace event store, and Power Profiler is iOS-only — so open it in Instruments.app instead), ornot_present(instrument wasn't in the recording). Silence never reads as "clean", and "couldn't measure" never reads as "measured, nothing found" - Symbolication –
--dsym <path>resolves raw0x…frames; without it, dSYMs are auto-discovered by UUID via Spotlight, and frames with no match stay raw and are flagged (never invented) - Output envelope & exit codes –
analyzedefaults to terse markdown (--json/--bothfor JSON);record,doctor, andcomparedefault to compact JSON (--humanfor text). Exit0ok ·2environment/usage error (xctrace missing, trace not found, bad args, refused gate) ·3regression found (compare --fail-on-regression) ·8output-write error - The record honesty caveat – an
xctrace record --launchcapture terminated at the time limit exits non-zero (it returns the killed target's status) while still saving a valid trace, sorecordtrusts the saved bundle, not the exit code, and reportsok: truewith an explanatorynotesentry
Recording Presets
record --preset <name> maps to a verified-on-Xcode-26 instrument set (names confirmed via xctrace list instruments). Use --template / --instrument instead for a narrow, ad-hoc capture.
| Preset | Instruments | Use |
|---|---|---|
cpu | CPU Profiler | "slow" / CPU bottlenecks (analyze round-trips) |
memory | Allocations, Leaks | growth, retain cycles (Instruments.app only) |
network | CPU Profiler, Network Connections | connections + bytes per process (analyze round-trips) |
energy | Power Profiler | battery (iOS/iPadOS only) |
full | CPU Profiler, Allocations, Leaks, Network Connections | macOS "find everything" |
full-ios | full + Power Profiler | iOS "find everything" |
Two instrument choices are deliberate and verified against real Xcode 26 exports: cpu uses CPU Profiler (schema cpu-profile), not Time Profiler; network uses Network Connections (schema network-connection-stat, socket-level, any process), not HTTP Traffic (which only captures URLSession traffic that analyze doesn't read). Allocations/Leaks stay in memory/full so the recording opens in Instruments.app, but analyze can't surface their data — see the support matrix note below.
xcprof record --preset cpu --attach MyApp --time-limit 10s # attach (no gate)
xcprof record --allow-launch --time-limit 10s -- /path/to/MyApp # launch from startup
xcprof record --preset cpu --attach MyApp --dry-run # preview the exact xctrace command
xcprof analyze MyApp.trace --json # structured reportDocumentation Scope
This page documents the xcprof-ref reference skill — the bundled Axiom CLI for capturing and analyzing Instruments traces.
- For Axiom's higher-level profiling agent, see the performance-profiler agent
- For the profiling slash command, see /axiom:profile
- For GUI-side profiling decision trees and the raw
xctraceCLI it wraps, see performance-profiling and xctrace - For field performance metrics from production users, see metrickit-ref
- For the sibling bundled tools, see Console Capture (xclog), Crash Symbolication (xcsym), and Simulator UI & Accessibility (xcui)