When to use this
- A profiler (CPU, wall-clock, flame graph) has run and the raw output needs interpreting.
- "It's slow" needs turning into a specific, measured bottleneck before anyone writes an optimization.
- Not a replacement for actually running a profiler -- this skill interprets its output; guessing at hot paths without measuring is how time gets wasted on the wrong fix.
The skill file
Copy this verbatim. It's written in the SKILL.md format (YAML frontmatter + markdown instructions) that Claude Code, and increasingly other agent tools, read directly.
--- name: performance-profiler-guide description: Interpret profiler output (CPU/wall-clock profile, flame graph) to identify the specific functions worth optimizing, distinguishing self time from cumulative time and checking whether the hot path is actually on the user-facing critical path. Use after a profile has been captured. --- # Performance Profiler Guide Never optimize from a guess. If no profile exists yet, the first recommendation is "profile it," not a speculative fix. ## Reading the profile correctly - **Self time vs. cumulative time**: a function with high cumulative time but low self time is slow because of what it calls, not itself -- optimize its callees. A function with high self time is where the actual work is happening. - **Call count**: a cheap function called a huge number of times can outweigh an expensive function called once. Multiply per-call cost by call count before ranking. - **Wall-clock vs. CPU time**: if wall-clock time is much higher than CPU time, the bottleneck is likely I/O/waiting (network, disk, lock contention), not computation -- a CPU profiler alone will mislead you here. ## Is it even worth fixing? Before recommending an optimization, check: is this hot path on the critical path a user actually experiences (e.g. request latency), or is it a background job where a few extra seconds don't matter? Optimizing the wrong thing is worse than not optimizing. ## Output Ranked list of the top few actual bottlenecks (not a full profile dump), each with self/cumulative time, call count, whether it's user-facing, and a concrete optimization direction (not yet the implementation -- confirm priority first).
Installing it elsewhere
The frontmatter/body split above is Claude Code's convention. Here's how to carry the same instructions into other tools:
Save the file below verbatim (frontmatter included) at that path, project-local or in ~/.claude/skills/ for a user-level skill. Claude Code loads the name/description pair to decide when to pull it in, or you invoke it directly as /performance-profiler-guide.
Convert the YAML frontmatter to Cursor's rule format (description, globs, alwaysApply: false) and keep the markdown body as the rule content. Cursor surfaces it by description match, same idea as Claude Code's auto-load.
Codex CLI (and increasingly other agentic CLIs) read AGENTS.md at the repo root as always-on instructions. Paste the markdown body under a heading like ## {title}; for GitHub Copilot's coding agent, the equivalent file is .github/copilot-instructions.md.
Append the markdown body to .windsurfrules at the repo root. Windsurf treats the whole file as always-on context, so keep only the instructions you want applied on every request.
- Optimizing the function with the biggest bar in the flame graph without checking self time vs. cumulative time -- you might be optimizing a leaf that isn't actually slow.
- Chasing CPU optimizations on a workload that's actually I/O-bound.
- Optimizing a hot path that isn't on any user-facing critical path.