agentleFS
mik2winmik2win/foureyes/skills/perf/SKILL.md

perf

Skill2 starsChanged 3 months agoMITView on GitHub

Measurement-first performance work — define the budget and metric, measure a reproducible baseline, profile to find the REAL hotspot, fix the biggest lever first (algorithmic > batching/caching > micro), re-measure after every single change, stop at the budget. TRIGGER when: something is slow, memory-hungry, or the user wants it faster/cheaper ("optimize", "why is this slow", "speed this up", "reduce latency/memory"). DO NOT TRIGGER when: it's a correctness bug that happens to involve time (timeout because of a hang → /diagnose), or a whole-codebase perf *audit* with no target metric (use the performance-analyzer agent directly).

19 other projects use a version of this.

Adopted by

Most recently taken up by

Used with

Projects with it also use security, debug and 5 more.

Other files people use alongside this one.

Files found in the same public projects as a version of this one, more often than they turn up anywhere else. Each project counts once, large collections count for less, and this file's own repository is left out.
  • 0xSeroSkill

    security

    Also in 4 projects that use this

  • AnthropicSkill

    debug

    Structured debugging session — reproduce, isolate, diagnose, and fix. Trigger with an error message or stack trace, "this works in staging but not prod", "something broke after the deploy", or when behavior diverges from expected and the cause isn't obvious.

    Also in 7 projects that use this

  • Microsoft AzureSkill

    docs

    Also in 4 projects that use this

  • Microsoft AzureSkill

    design

    Design rules and conventions for the API Center Portal. Use when editing detail pages, card components, badges, layout, navigation, sidebars, or headers. Covers badge styling, metadata placement, page navigation patterns, and layout alignment.

    Also in 4 projects that use this

  • SentrySkill

    review

    Fixture review skill.

    Also in 8 projects that use this

  • SentrySkill

    spec

    Produce a verified spec — problem, desired outcome, and acceptance criteria — before building. Use when given a GitHub/Linear issue link, when starting from a fuzzy in-conversation idea, or asked to "figure out what to do" / "scope this" / "what should I build" — whenever the *what* isn't yet pinned down. Grills the ambiguities, checks the premise against the code, and produces acceptance criteria you sign off on — then hands to design-first.

    Also in 3 projects that use this

The file

We split this skill into the rules it gives an agent

5 rules. 0 are common, 2 are distinctive, and 3 are very specific to this project.

  • 0

    Common

    Most of the 14 edited versions we read keep these.

  • 2

    Distinctive

    This author's own choices. Worth a look.

  • 3

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Very specific:

    Read .claude/PROJECT.md (Commands — test/run/bench if present.

    line 29
  2. Distinctive:

    If the operation can't be exercised reproducibly, that's the first task — a perf fix you can't measure is a guess wearing a stopwatch.

    line 59
  3. Very specific:

    Use the stack's profiler (from rules/PROJECT.md.

    line 64
  4. Distinctive:

    If the work is a graph rather than a line (pipeline, fan-out, parallel jobs), the profile is the critical path through it: time cut off …

    line 70
  5. Very specific:

    Caching is a liability, declared: every cache added names its invalidation trigger, staleness bound, and memory ceiling — an uninvalidated …

    line 93

“Common” is measured: kept by at least 6 in 10 of the 14 edited versions of this file we could read. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

Performance Work: $ARGUMENTS

Principle

No optimization without a measurement — intuition names the wrong hotspot more often than not, and a model's intuition is trained on other people's codebases. The profile decides where to work; the baseline decides whether it worked; the budget decides when to stop. An optimization that was never measured is a complexity purchase with an unknown price and an imagined benefit.

Phase 0 — Load profile

Read .claude/PROJECT.md (Commands — test/run/bench if present; Architecture; Integrations — external calls are frequent culprits) and applicable rules. Missing/TEMPLATE → fall back to the root CLAUDE.md (always in context) when it carries those facts, noting you're running without a kit profile; only if neither has them, STOP, /bootstrap first.

Phase 1 — Budget and metric (before any code is read)

  • One metric, named precisely: p95 latency of endpoint X / wall-time of job Y / RSS after N ops / cold-start / throughput — not synonyms. Throughput trades against response time, and responsiveness (how fast the request is acknowledged) is a third axis, answered by a job id and progress, not by shorter work. "Faster" is not a metric; ask which is meant.
  • The budget: the number at which this is done ("p95 < 300ms", "import of 100k rows < 2min"). From the user if it's product-facing (one question, with your recommended number); from you (stated) if it's internal. No budget → no stopping criterion → optimization becomes a hobby — don't start without one.
  • Realistic load shape: the N, the data skew, the concurrency this must hold at (code-quality.md → algorithmic sizing). Measuring at toy N is measuring nothing.
  • Floor before the profile: serial waits on the path add up; parallel ones cost the slowest alone. Floor already over budget → escalate per Phase 5, don't profile.
  • Rank the outcomes the budget implies: fast success > fast failure > slow success > slow failure. Past the budget a slow answer is not a partial success — it holds resources on both sides, and from outside "very slow" and "down" look the same. Say what the path does when it exceeds the number: refuse, degrade, or take the work off the caller's clock.

Phase 2 — Baseline, reproducibly

Build the smallest repeatable measurement: the profile's bench command, a timing harness around the real operation, or a scripted request loop — warm-up excluded, ≥3 runs, report median + spread. Save the exact command in the report so anyone can re-run it. Build it at production's construct-to-call ratio — the wrong ratio validates the opposite fix. If the operation can't be exercised reproducibly, that's the first task — a perf fix you can't measure is a guess wearing a stopwatch.

Phase 3 — Profile: find where the time actually goes

Use the stack's profiler (from rules/PROJECT.md; WebFetch its docs if unsure — not from memory). No profiler available → bisect with coarse timers around the operation's phases. Predict before you peek (core.md): write down where you think the time goes, then look — a wrong prediction here is the cheapest possible lesson about this codebase. Attribute the budget: "78% in <fn> at path:line, of which 60% is the N+1 to <service>". The top item is the only sanctioned target. If the work is a graph rather than a line (pipeline, fan-out, parallel jobs), the profile is the critical path through it: time cut off that path changes the total by nothing.

Phase 4 — Fix the biggest lever, one change at a time

Lever order — never micro-tune while a bigger lever is unpulled:

  1. Don't do the work: cache the answer, dedupe the calls, early-exit, move it off the hot path / async, do it once at startup.
  2. Do it in bulk: batch the N+1 (queries, HTTP, IPC), vectorize, stream instead of materializing.
  3. Do it with the right algorithm/structure: the O(n²) scan → index/hash/sort; the linear search in a loop → set; per code-quality.md sizing.
  4. Micro: allocation churn, serialization, hot-loop costs — only inside the measured hotspot, only after 1–3 are exhausted.

Per change: state the expected effect ("batching should cut ~60% of the 78%"), apply one change, re-run Phase 2, keep or revert on the numbers. Two changes at once = attribution destroyed. Correctness stays gated: the suite runs after each kept change. Put the compromise in the effect layer. Batching, paging and caching belong in the code that already does I/O — keep domain functions phrased over "zero or more X". Purity is not the test: one that grew a page_size or a cursor is still pure and now knows the storage.

Caching is a liability, declared: every cache added names its invalidation trigger, staleness bound, and memory ceiling — an uninvalidated cache is a scheduled /diagnose session, and a key missing anything the answer depends on (including what the handler mixes in while building it) serves one user's data to the next. Name the reads that must never be cached — user-scoped, time-sensitive. The same question is owed by everything else a change accumulates — rows, log files, files on disk, an in-memory seen-set: name what reclaims it, in this change. An unbounded key space is not yet a cache. Precomputed derived data has two paths. Precompute for the rows read often enough to pay for the write, compute on read for the tail — then say which rows fall on which side, and what a read costs when the hot ones turn out to be in the tail. That case decides the split.

Phase 5 — Stop at the budget

Budget met → stop. Further optimization is negative-value work: complexity bought with no requirement behind it. Report over-budget ideas as a ranked "if it's ever needed" list instead of implementing them. Budget NOT reachable at this altitude (the architecture is the bottleneck — sync pipeline, chatty protocol, wrong storage) → stop and escalate per core.md: that's a /prepare-level redesign decision, not a hot-loop patch.

Report

## Perf: <operation> — <BUDGET MET / NOT MET / ESCALATED>
Metric & budget · Baseline → Final (median ± spread, exact command)
Profile: where the time went (top-3, % + path:line)
Changes kept: <one line each — lever, expected vs actual effect, domain signature it changed>
Changes reverted: <what didn't pay + the number that said so>
Caches added: <trigger / staleness / ceiling> or none
Regression guard: <perf test / bench command + threshold recorded where>
Not optimized (over budget met): <ranked list>

Handed a plan or card file? Append this report to it as ## Perf Log — <date> — <verdict>, following ../implement/reference/work-log.md. Keep the ledger and deviations on disk during the run. The re-measure on the production host goes under Re-check later. List the file in the commit suggestion. No artifact → the report stays in chat.

Offer to add the bench command + threshold as a regression guard (a perf test or a CI step) — a perf win without a tripwire erodes silently.

Hard rules

  • No edit before a baseline; no keep without a re-measure. Numbers, not adjectives.
  • One change per measurement.
  • The profile picks the target — never optimize code the profile didn't indict, however ugly it looks (route that to /refactor as a separate pass).
  • Suite green after every kept change — a fast wrong answer is a regression.
  • Report expected-vs-actual for every change: misses are calibration data, not shame.

See also

  • performance-analyzer agent — broad audit / second opinion on a hotspot.
  • /diagnose — when "slow" is actually "hanging/broken"; /rollout — shipping a risky perf change behind a flag; rules/_generic/core.md — predict-before-peek.

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.