performance-audit
A Claude Code skill (and matching Cursor rule) that statically audits a NestJS + Next.js + Prisma + PostgreSQL codebase for performance anti-patterns and produces a severity-ranked report.
No server needs to be running — it works by scanning source code, not by profiling a live app.
What it finds
35 rules across 5 layers:
| Layer | Covers |
|---|---|
| D — Prisma / data access | N+1 queries, unbounded findMany, over-fetching, unbounded raw SQL, slow work inside transactions, unbounded parallel I/O |
| A — NestJS API | Blocking sync calls in the request path, unpaginated list endpoints, sequential external calls, unbounded in-memory caches |
| F — Next.js / React | Heavy client bundles not code-split, needless 'use client', client-side initial data fetching, missing debounce on search inputs |
| S — PostgreSQL schema | Missing indexes on foreign keys / hot query fields, unanchored ILIKE search, unindexable vector columns |
| G — Algorithmic complexity | O(n²) patterns: repeated linear lookups in loops, nested pairwise comparisons, sorting inside loops, spread-accumulator copies, JSON.parse(JSON.stringify()) clones |
Each rule maps to a grep pattern, but every hit is verified in context before being reported — known false positives (bounded queries, small fixed-size collections, sequential awaits with a real data dependency, etc.) are filtered out. It never modifies code — it only produces a report.
Install
Copy this folder into your project:
# Claude Code
cp -r performance-audit /path/to/your-project/.claude/skills/
# Cursor
cp performance-audit.mdc /path/to/your-project/.cursor/rules/
That's it — no dependencies, no build step.
Use
Just ask, in either tool:
check performance find slow queries why is the app slow performance audit the candidate module
You can scope it ("check performance in packages/api only") or ask for a quick pass ("quick performance check" runs only the High-severity rules).
Requirements
- Detects your stack automatically and skips layers that don't apply (e.g. no
*.prismafiles → Layer D and S are skipped). Layer G (algorithmic complexity) always runs since it's plain TS/JS, not framework-specific. - Built and tuned against a NestJS + Next.js + Prisma + PostgreSQL monorepo, but the D/A/F/S layers degrade gracefully on partial stacks (e.g. NestJS without Next.js), and G works on any TS/JS project.
Output
A markdown report ranked High → Medium → Low, each finding with file:line, why it's slow, and a concrete fix:
# Performance Audit — 2026-07-09
Layers scanned: D, A, F, S, G (skipped: none)
## High
1. `src/foo.service.ts:123` — [D1] N+1: one query per candidate in `.map(async)`
Why slow: N candidates → N+1 round-trips; grows linearly with data.
Fix: single `findMany` with `where: { id: { in: ids } }`, or `include` the relation.
Reports over 20 findings are also saved to performance-audit-report.md in the repo root.
License
MIT — use it, fork it, adapt the rules to your own stack.