agentsclimarketplace

Perf hunter

Skill ak-ship/fullstack-agent-skills/skills/perf-hunter

15 production-grade Claude Code skills that turn it into a full-stack engineering agent — design, code, test, secure, ship. Also works with OpenAI Codex CLI. MIT.

Install
npx -y skills add ak-ship/fullstack-agent-skills --skill perf-hunter

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

One thing to look at

  • 0 stars0 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

What its author says it does

Copied from the file, not written here

Find and fix the actual bottleneck — not the one you assume. Profiles before optimizing, measures before and after, refuses to "rewrite for perf" without numbers. Covers React/Vue rendering, bundle size, database query plans, N+1 patterns, memory leaks, and Node.js event-loop lag. Use when the user says "make this faster", "why is this slow", "optimize this", "the page is laggy", "the query is slow", or "this endpoint times out".

SKILL.md

8.0 KB, as published. Nobody here has run it

perf-hunter — measure, fix, measure again

When to use this skill

Trigger when something is slow and someone wants it faster. Strong signals:

  • "why is this slow?", "make this faster", "this is too slow"
  • "the page takes 5 seconds to load"
  • "the query times out"
  • "we're hitting our function memory limit"
  • A flame graph, profiler output, or DevTools screenshot pasted in

Do not trigger for: code style optimizations that don't have measured impact (use refactor-master), perceived perf issues without numbers ("it feels slow") — get numbers first.

The output contract

A perf change that:

  1. Has a before number — measured under realistic conditions, not synthetic best-case.
  2. Targets the actual bottleneck — identified by profiling, not guessing.
  3. Has an after number — same measurement, same conditions.
  4. Quantifies the trade-off — what got harder to maintain, what runtime cost moved where.
  5. Includes a regression test — a benchmark or a budget that fails if the perf regresses.

Without those four numbers and a regression test, it's not a perf fix — it's vibes.

Workflow

1 — Define "slow"

Get specific:

  • What operation? (page load, API call, query, render, build)
  • How slow? (p50, p95, p99 — averages lie)
  • Compared to what? (target, prior version, competitor)
  • Under what load? (1 user vs 1000, cache cold vs warm, payload size)

If the user can't answer those, ask. Optimizing the wrong p50 doesn't move the p95 the users notice.

2 — Measure before

Pick the right tool for the surface:

Frontend:

  • Chrome DevTools Performance panel — record a real interaction, find the long tasks
  • Lighthouse for page-load metrics (LCP, INP, CLS, TBT)
  • React Profiler for component render times
  • webpack-bundle-analyzer / rollup-plugin-visualizer / source-map-explorer for bundle size

Backend Node:

  • --prof for CPU profiling, then node --prof-process → flame chart with 0x or clinic flame
  • clinic doctor for high-level (event-loop lag, GC, CPU, memory)
  • clinic bubbleprof for async I/O patterns
  • For HTTP: autocannon or k6 for load + percentiles

Database:

  • EXPLAIN ANALYZE for the slow query (Postgres) — read the actual plan
  • pg_stat_statements extension to find the queries burning the most time across the workload
  • EXPLAIN FORMAT=JSON (MySQL), db.collection.explain('executionStats') (Mongo)

Record numbers. Don't proceed without them.

3 — Diagnose

Common patterns and the smell they leave:

N+1 queries — code makes one query, then loops and queries per result. Smell: many identical queries in the log, total query count ~= result count.

  • Fix: IN (...) batch, JOIN, or a DataLoader-style batcher.

Sequential awaits when parallel worksfor (const id of ids) { await fetch(id) } is N round-trips. Smell: latency scales with N.

  • Fix: await Promise.all(ids.map(fetch)). Cap concurrency with p-limit if needed.

Re-renders in React — child renders even when its props haven't changed. Smell: React Profiler shows wide flame.

  • Fix: lift state, useMemo for derived values, React.memo for components, stable references for callbacks. Don't sprinkle these — find the actual culprit first.

Bundle bloat — initial JS payload is 800kB+. Smell: Lighthouse LCP poor, FCP fine.

  • Fix: dynamic import() for non-critical routes, tree-shake (look for import * as X), check for whole libraries imported for one function (date-fns sub-imports, lodash-es).

Missing indexes — sequential scan on a 10M-row table. Smell: EXPLAIN ANALYZE shows Seq Scan + high actual time.

  • Fix: targeted index. Validate with EXPLAIN ANALYZE that the plan changed.

Bad index usage — index exists but planner skips it. Smell: EXPLAIN shows Filter after the scan rather than Index Cond.

  • Fix: usually a type mismatch in the query (WHERE id = '123' against integer column), or stale statistics (ANALYZE).

Memory leak — RSS climbs over hours/days, never plateaus. Smell: process restarts every N days "for hygiene".

  • Fix: heap snapshots before/after a workload; look for unbounded caches, retained closures, untracked subscriptions, growing Maps indexed by request ID.

Event-loop lag — Node app's response times balloon under load even though the work is async. Smell: clinic doctor shows lag > 50ms.

  • Fix: usually a sync CPU-heavy step (JSON.parse of a huge body, regex, crypto on the request thread) — move to a worker_thread or off the request path.

4 — Fix the one thing

Apply the smallest change that addresses the diagnosis. Don't pre-optimize the next thing you "noticed while you were there".

5 — Measure after

Same tool, same scenario, same load. Record the new number. Report the delta in absolute and relative terms:

Before: p95 endpoint latency 1240ms
After:  p95 endpoint latency 180ms  (-85%)
Trade-off: added an in-memory index that uses ~40MB heap per worker.

If the after number didn't move, revert. The fix wasn't the right one.

6 — Lock the win

Add a regression guard:

  • Backend: a perf test in CI (autocannon or k6 with a p95 threshold)
  • Frontend: bundle-size budget (@bundle-analyzer/cli, Next.js experimental.bundlePagesRouterDependencies, or bundlewatch)
  • DB: a query that the test suite runs EXPLAIN ANALYZE on, asserting the plan uses the new index

Without a guard, the fix decays. The next refactor will un-do it silently.

Patterns and anti-patterns

Do:

  • Optimize the hot path. 80% of latency typically lives in 20% of the code. Profile.
  • Cache at the right layer — closest to the consumer that can tolerate the staleness. Browser, CDN, app-memory, Redis, DB materialized view.
  • For DB perf: read the plan. The plan tells the truth; intuition lies.
  • Save a copy of the profile/flame chart in the PR — future you will need to know what the world looked like before.

Don't:

  • Don't add a cache without an invalidation plan. The bugs you create with a stale cache are worse than the latency you save.
  • Don't useMemo everything in a React component. Memoization itself costs CPU and memory. Profile first.
  • Don't switch from REST to GraphQL "for perf". The wire format isn't usually the bottleneck.
  • Don't rewrite in Rust/Go/etc. before you've fixed the obvious things in the current stack.
  • Don't optimize what runs once. A 10x speedup on a script that runs at deploy time is worth nothing.

Example invocation

User: "Our /api/dashboard endpoint takes 4 seconds. Make it fast."

  1. Get numbers: p95 is 4.2s, p99 is 7s, cache cold. Target: p95 < 500ms.
  2. Profile: turn on Postgres log_min_duration_statement = 100. Make one request, check the log.
  3. Diagnose: 47 queries logged. Looks like N+1 — for each org member, the code fetches their last 5 activities individually.
  4. Fix: replace with one batched query joining users + activities + filtering for "last 5 per user" via a window function. Single query, ~20ms.
  5. Measure after: p95 down to 180ms. Trade-off: query is longer to read, added a comment explaining the window function.
  6. Lock: add a EXPLAIN ANALYZE assertion in the integration test that the plan uses the (user_id, created_at DESC) index.
  7. Report: -96% latency, single query replaces 47, regression test in place.

See also

  • code-auditor — to find the N+1 patterns and unbounded loops before they're slow
  • schema-architect — when the fix is an index that the schema is missing
  • refactor-master — when the perf fix is structural (e.g., pulling I/O out of a hot loop)

Keep looking

Skills are one crate of 328,083. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.