Documentation
Installation & Usage
Get started with SPAA in minutes
Installation
SPAA is distributed as a Rust crate and can be installed via Cargo. This installs three binaries: dtrace_to_spaa, chrome_to_spaa, and heapdiff.
cargo install spaaPrerequisites: You need Rust and Cargo installed. If you don't have them, install via rustup.rs
Quick Start
Convert a DTrace profile
Run DTrace to collect a CPU profile, then convert it to SPAA format:
sudo dtrace -n 'profile-997 { @[ustack()] = count(); }' -o profile.txtdtrace_to_spaa profile.txt -o profile.spaaConvert Chrome DevTools data
Convert CPU profiles or heap snapshots from Chrome DevTools:
chrome_to_spaa trace.json -o cpu.spaachrome_to_spaa Heap.heapsnapshot -o heap.spaaFind memory leaks with heapdiff
Compare two Chrome heap snapshots to identify memory leaks:
heapdiff baseline.heapsnapshot after-action.heapsnapshot -o diff.ndjsonCLI Tools
dtrace_to_spaa
Converts DTrace aggregated stack output to SPAA format.
dtrace_to_spaa input.txt -o output.spaa
dtrace_to_spaa input.txt --event syscall::read:entry --frequency 0Options
-o, --outputOutput file (defaults to input with .spaa extension)-e, --eventEvent name (default: profile-997)-z, --frequencySampling frequency in Hz (inferred from event name if possible)-f, --formatInput format: aggregated (default), split, per-probechrome_to_spaa
Converts Chrome DevTools profiling data to SPAA format. Automatically detects the input type.
chrome_to_spaa trace.json # Performance panel trace
chrome_to_spaa profile.cpuprofile # V8 CPU profile
chrome_to_spaa Heap.heapsnapshot # Memory panel snapshot
chrome_to_spaa timeline.heaptimeline # Allocation timelineOptions
-o, --outputOutput file (defaults to input with .spaa extension)heapdiff
Compares two Chrome heap snapshots to identify memory leaks. Outputs an agent-friendly NDJSON format showing object type growth and retention paths.
heapdiff baseline.heapsnapshot target.heapsnapshot -o diff.ndjsonOptions
-o, --outputOutput file (defaults to stdout)-n, --max-retainedMaximum retained objects to analyze (default: 100)Library Usage
The spaa_parse crate provides types and parsers for working with SPAA files in Rust:
use spaa_parse::{SpaaReader, Record};
use std::fs::File;
use std::io::BufReader;
let file = File::open("profile.spaa")?;
let reader = SpaaReader::new(BufReader::new(file));
for record in reader {
match record? {
Record::Header(h) => println!("Source: {}", h.source_tool),
Record::Stack(s) => println!("Stack {} has {} frames", s.id, s.frames.len()),
_ => {}
}
}Agent Skill
Install the SPAA analysis skill to give your AI coding agent the ability to analyze performance profiles:
npx skills add andrewimm/spaaThe skill teaches agents how to:
- Parse SPAA files using
head,tail,grep, andjq - Find CPU hotspots and hot functions (exclusive time)
- Identify memory leaks via
live_bytesmetrics - Reconstruct call stacks from frame IDs
- Filter by thread, event type, or time window
Claude Code
Supported
Cursor
Supported
Skills-compatible
Supported
Working with SPAA Files
SPAA files are NDJSON (newline-delimited JSON), making them easy to query with standard command-line tools:
View the header (first line)
head -1 profile.spaa | jq .Find all stack records
grep '"type":"stack"' profile.spaa | head -5Extract frame information
grep '"type":"frame"' profile.spaa | jq '{id, func, srcline}'Find hottest stacks by sample count
grep '"type":"stack"' profile.spaa | \
jq -r '[.weights[] | select(.metric=="samples") | .value][0] as $v | "\($v)\t\(.id)"' | \
sort -rn | head -10Filter stacks by thread ID
grep '"type":"stack"' profile.spaa | jq 'select(.context.tid == 4511)'