| name | performance-review |
| description | Review a codebase for performance issues โ N+1 queries, algorithmic complexity, unbounded reads, blocking I/O in hot/async paths, missing caching, connection-pool misuse, and redundant work โ like a senior engineer's performance audit. Use whenever the user asks why code is slow, whether it will scale, to find bottlenecks or hot paths, or to review/audit for performance or scalability โ even without the word "review". |
performance-review
Reviews an entire codebase (v1 scope โ not a diff or PR review) for
static, source-visible performance issues. Sibling skill to
implementation/security-review, sharing the same overall shape (whole
codebase, LLM-judgment-heavy, no neutral IR) but a different lens.
Purely static โ there's no execution environment available to this
skill, so every finding is inferred from reading code, never from measured
latency/profiling data. Frame findings accordingly ("this pattern will
degrade at scale," not "this takes 400ms").
Requires: scripts/scan.py and implementation/_shared/file_enum.py
(stdlib-only Python 3). install.sh places these automatically.
Step 1 โ Resolve the input
Accept a directory path (the codebase root to review). If nothing is
given, ask for one.
If the user separately mentions a schema.ir.json (from rfc-to-schema)
or api.ir.json (from rfc-to-api) they want cross-checked, note its
path for Step 4. Only use these if explicitly pointed at โ never
search the repo for them, same convention as security-review (these
artifacts typically live in a jobs/-style directory, not next to the
source).
Step 2 โ Run the structural pre-pass
python3 <skill_dir>/scripts/scan.py --root PATH
This returns JSON with files (the filtered reading list โ vendor,
binary, lockfile, and .gitignore-matched paths already excluded) and
skipped (what was excluded and why). There is deliberately no
content-analysis heuristic pass โ a regex can't tell a 3-item config
loop from an unbounded one. Read every file in files directly.
Scoping (large codebases only): if files contains more than 150
entries, ask one question via AskUserQuestion before reading โ options:
review everything (slower, complete), focus on a subtree the user names,
or focus on request-handling/entry-point paths first. Skip this entirely
below the threshold, or when the user's request already scoped the review.
Step 3 โ Read the code
For every file in files, look for these five categories (skip one
entirely, and say so, only if genuinely inapplicable โ e.g. no
network/file I/O anywhere in the codebase):
- N+1 queries โ a loop that issues a DB/ORM/network call per
iteration instead of a single batched call.
- Algorithmic complexity red flags โ nested loops over the same
collection, or any pattern that's quadratic-or-worse on data that's
realistically unbounded. Don't flag nested loops over a fixed-size,
small collection (e.g. a handful of config entries) โ that's noise.
- Missing pagination / unbounded reads โ "fetch all" with no limit,
especially in a request-handling path or on a table/collection that
plausibly grows without bound.
- Blocking I/O in hot/async paths โ a synchronous network/file/DB
call inside code that's otherwise async, or inside a loop in a
request-handling path where it'll be repeated per-item instead of
run concurrently.
- Redundant work โ re-parsing/re-serializing/re-computing the same
data on every loop iteration when it could be hoisted out and computed
once.
- Missing caching โ the same expensive read (config fetch, remote
lookup, heavy computation) repeated per-request or per-iteration with
no memoization or cache layer, where the value is obviously reusable.
- Connection/client churn โ creating a new DB connection, HTTP
client, or session object per request/iteration instead of reusing a
pooled/module-level one.
Codebase-wide patterns matter more than isolated lines โ if the same
inefficiency recurs across many call sites (e.g. the same N+1 pattern in
every list endpoint), report it as one systemic finding listing every
affected location, not N near-duplicates.
Step 4 โ Optional: cross-check against the RFC pipeline
Only if the user explicitly pointed you at these artifacts in Step 1:
schema.ir.json โ for fields you observe the code actually
querying/filtering/sorting by, check whether the IR declares that field
unique or otherwise indexed. A field the code hits on every request
with no indexing signal in the schema is a real, checkable finding โ
this is how this skill covers "missing index" without guessing at DB
internals directly from application code.
api.ir.json โ for each operation declared paginated: true with
a pagination_style, verify the handler actually applies a
limit/cursor. A mismatch is real, checkable drift.
Report both under an RFC/implementation drift section โ same
name/pattern as security-review's, not new vocabulary โ since this
check only exists because the pipeline artifacts happened to be
available, not because every finding of this kind implies one.
Step 5 โ Assemble findings
Each finding needs: file, line(s), category (one of Step 3's seven),
severity, confidence, a description, and a concrete suggested fix
(name the actual mechanism: batch via WHERE id IN (...), add a LIMIT/
cursor, hoist the parse out of the loop, use an async HTTP client โ not
just "make this faster").
Severity (impact at realistic production scale, not correctness):
- Critical โ will cause timeouts/outages/unusable latency at
expected scale (e.g. N+1 on a list endpoint already handling hundreds
of items).
- High โ meaningfully degrades latency/throughput under normal, not
just worst-case, load.
- Medium โ real inefficiency, but only matters well beyond currently
plausible scale, or in a rarely-hit path.
- Low โ minor/theoretical, correct-but-not-optimal, worth a mention
not a fix-now.
Confidence (how sure this is a real problem, not a misread):
- High โ traced the full path; no mitigating factor visible (e.g. no
batching/caching layer above this code).
- Medium โ the pattern looks wrong but a framework-level mitigation
might exist that isn't visible in this file (e.g. ORM lazy-load
batching, an upstream cache).
- Low โ flagged out of caution; plausible this is a non-issue.
For every Medium/Low-confidence finding, add a one-line false-positive
note (e.g., "might already be batched if this ORM's select_related is
configured elsewhere โ verify"). Never drop a finding purely for low
confidence.
Step 6 โ Write the report
Write PERFORMANCE_REVIEW.md next to the codebase root reviewed (or cwd
if the root has no clear parent worth writing into), and show it inline โ
both. Structure:
- Summary line โ count per severity tier.
- Findings, grouped by severity (Critical first), each with
category, confidence, description, and suggested fix.
- RFC/implementation drift (if Step 4 ran), its own section.
- Scan coverage โ files reviewed vs. skipped, and why.
- Out of scope โ note that this is a static review only: memory
leaks and true root-cause latency require runtime/profiling data this
skill doesn't have access to; recommend profiling in staging/prod if
the codebase's scale makes that worthwhile.
No single approve/reject verdict for a whole codebase โ the severity
summary is the top-line signal, same as security-review.
Every invocation is treated as a fresh review โ this skill does not
track prior reviews or diff against an earlier scan in v1.
Step 7 โ Offer follow-ups
After presenting the report, offer concrete next steps via AskUserQuestion โ
e.g. "Explain finding N in more depth", "Draft a fix for the top finding",
"Re-run scoped to " โ and also accept free-form follow-up
questions. Only draft or apply code fixes when the user explicitly picks
that option; never edit the reviewed codebase unprompted. When drafting a
fix, show a diff and let the user decide whether to apply it.
Rules
- Don't claim measured latency/timing โ every finding is inferred from
reading code, not runtime data.
- Don't flag nested loops over small, fixed-size collections as
algorithmic complexity issues.
- Don't search the repo for
schema.ir.json/api.ir.json โ only use
them if the user explicitly points you at one.
- Don't drop findings for low confidence โ flag with a false-positive
note instead.
- Don't report N near-duplicate findings for one systemic pattern โ
merge into one finding listing every affected location.
- Don't edit the reviewed codebase unless the user explicitly asks for a
fix to be applied.