| name | dev-perf |
| description | Profile, optimize, and benchmark performance โ measure baseline first, find the real bottleneck, optimize one thing at a time, prove it with numbers. Use on "it's slow", "optimize this", "improve performance", "reduce latency", "profile this", or shared timing/benchmark output. |
| argument-hint | [lite|full|ultra] |
Perf
Measure โ profile โ optimize โ verify. Never optimize without a measured baseline.
Delivery Mode (lite | full | ultra, default lite)
Mode is the trailing argument when it is exactly lite, full, or ultra; everything else is the task/feature description. No mode given โ lite.
lite (default) โ one commit covering every optimization.
full โ one commit per bottleneck fixed, same branch.
ultra โ independent candidates benchmarked in parallel worktrees; merge only those clearing the bar.
1. Define the Target
Agree what "fast enough" means: current behaviour, target ("under 200ms"), workload. No target given โ ask.
2. Measure Baseline
go test -bench=. -benchmem ./...
npx clinic flame -- node server.js
pytest --benchmark-only
hey -n 10000 -c 100 http://localhost:3000/endpoint
Record p50/p95/p99 or ops/sec + memory โ an average hides tail latency.
3. Profile
Never optimize on intuition:
go test -bench=BenchmarkFoo -cpuprofile=cpu.prof && go tool pprof -http=:8080 cpu.prof
py-spy record -o flame.svg -- python script.py
perf record -F 99 -g -- <command>
State it before coding: "Bottleneck: <function>, 73% of CPU. Cause: N+1 query in loop." Trust the profile.
4. Optimize One Thing at a Time
Fix the top bottleneck only; re-measure before the next โ earlier fixes often eliminate later ones.
| Bottleneck | Fix |
|---|
| N+1 queries | Batch with IN (...) or join; index the join column |
| Missing index | EXPLAIN; index the WHERE/JOIN/ORDER BY column |
| Repeated computation in loop | Hoist or memoize |
| Hot-path allocations | Reuse buffers; pool |
| Per-request serialization | Cache serialized form; faster codec |
| Blocking I/O in async context | Async I/O or worker thread |
| Fetching unused data | Select needed columns; paginate |
Touch only the hot path; keep before/after obvious in the diff; tests still pass. full: re-measure + commit per bottleneck, repeat ยง3โยง6. lite: iterate internally, one commit at the end.
5. Measure Again
Same benchmark as ยง2. Before: p50 450ms p99 2100ms 12MB โ After: p50 38ms p99 120ms 9MB (-92%/-94%). Improvement <10% โ revert, look elsewhere.
6. Commit
Commit hygiene and message style: see the git-safe skill (no Co-authored-by:, git add -u not -A, imperative why-focused subject).
git add -u && git commit -m "perf: <what changed> โ p99 2100ms โ 120ms" โ numbers in every perf commit.
7. Report
Target, bottleneck (from profiler), fix, before/after/delta, tests status, remaining ("next bottleneck" or "target achieved"). If the target is unreachable without structural change (caching layer, different algorithm), say so plainly.