performance-audit

star 1

Performance audit of the codebase — identifies N+1 queries, missing indexes, slow queue jobs, unoptimized data access patterns, and Redis cache opportunities. Produces a prioritized report.

luispoliveira By luispoliveira schedule Updated 5/21/2026

name: performance-audit description: Performance audit of the codebase — identifies N+1 queries, missing indexes, slow queue jobs, unoptimized data access patterns, and Redis cache opportunities. Produces a prioritized report. license: MIT compatibility: NestJS + Next.js monorepo metadata: author: project version: "1.0"

Audit this NestJS + Next.js monorepo for performance issues. Focus on database access patterns, queue configuration, caching, and response size.

Do not modify anything. This is a read-only analysis.


Audit Areas

1. Database — N+1 Queries

The most common performance killer. Look for loops with database calls inside:

# Find potential N+1 patterns (db call inside loop)
grep -r "for.*await.*this\.db\|forEach.*await.*this\.db\|map.*await.*this\.db" apps --include="*.ts" -n

# Find missing 'include' on relations
grep -r "this\.db\.\w*\.findMany\|this\.db\.\w*\.findFirst" apps --include="*.ts" -n

For each findMany, check:

  • Are related entities fetched in a loop? → N+1
  • Should they be included with include: { ... }?
  • Is a select clause limiting fields returned?

2. Database — Missing Indexes

# Check schema for @index annotations
grep -r "@@index\|@index" packages/database/prisma --include="*.prisma" -n

# Find columns used in where clauses that may lack indexes
grep -r "where:.*{" apps --include="*.ts" -n

For each field used in where, orderBy, or cursor, verify a @@index exists in the schema.

3. Pagination

# Find queries without pagination
grep -r "findMany(" apps --include="*.ts" -n | grep -v "take\|skip"

# Verify PaginatedUtil usage
grep -r "PaginatedUtil\|paginationSchema" apps --include="*.ts" -n
  • Every findMany on a potentially large collection should have skip + take
  • take should be capped (max 100 via paginationSchema)

4. Bull Queue Configuration

# Check job options
grep -r "attempts\|backoff\|removeOnComplete\|removeOnFail" apps --include="*.ts" -n

# Check for unbounded queues
grep -r "removeOnFail\|removeOnComplete" apps --include="*.ts" -n

Required job options (per CLAUDE.md):

  • attempts: 3
  • backoff: { type: 'exponential', delay: 2000 }
  • removeOnComplete: true
  • removeOnFail: 500

Missing removeOnFail → unbounded Redis memory growth.

5. Redis — Cache Opportunities

# Check for repeated identical DB queries
grep -r "this\.db\." apps --include="*.ts" -n | sort | uniq -c | sort -rn | head -20

Look for:

  • Repeated lookups by ID (user by ID on every request)
  • Static/slow-changing data (config, roles) fetched per request
  • Session data fetched multiple times per request

6. HTTP Response Size

# Check for missing select clauses (fetching entire models)
grep -r "findMany({\s*where\|findFirst({\s*where\|findUnique({\s*where" apps --include="*.ts" -n | grep -v "select"

Always use select to return only needed fields — especially on list endpoints.

7. Next.js Performance

# Check for client components that could be server components
grep -r "'use client'" apps/web --include="*.tsx" -n

# Check for missing Suspense boundaries
grep -r "async.*export default function\|await.*fetch" apps/web/src/app --include="*.tsx" -n
  • Data fetching should happen in server components where possible
  • Add loading.tsx files for route-level Suspense boundaries
  • Check for unused client-side state management

8. Logging Overhead

# Check logging in hot paths
grep -r "this\.logger\.\|console\.\|Logger\." apps --include="*.ts" -n | grep -v "error\|warn"
  • Debug/verbose logging in hot paths (health checks, frequent events) → overhead
  • Verify health check paths are silenced (/health, /metrics in pino config)

9. Throttling Configuration

grep -r "ThrottlerModule\|ttl\|limit" packages/shared/src --include="*.ts" -n

Default: 10 req / 60s per IP. Evaluate if this is appropriate for each endpoint type.


Output Format

## Performance Audit Report

### CRITICAL (Blocking production scale)
| # | Issue | Location | Estimated Impact |
|---|-------|----------|-----------------|
| 1 | N+1 on user.findMany (relations loaded in loop) | apps/api/src/users.service.ts:45 | O(n) queries |

### HIGH (Address soon)
| # | Issue | Location | Recommendation |
|---|-------|----------|---------------|

### MEDIUM (Optimization opportunity)
| # | Issue | Location | Recommendation |
|---|-------|----------|---------------|

### PASSED CHECKS
- ✓ All findMany calls paginated
- ✓ removeOnFail set on all queue jobs
- ...

### Quick Wins
- [ ] Add `include` to users.findMany at users.service.ts:45
- [ ] Cache config lookup at config.service.ts:23 (changes rarely)

Guardrails

  • Never modify code — read only
  • Estimate query count impact where possible (O(1) vs O(n))
  • Distinguish between "will cause issues at scale" vs "already causing issues"
  • Reference specific file paths and line numbers for every finding
Install via CLI
npx skills add https://github.com/luispoliveira/nestjs-nextjs-monorepo --skill performance-audit
Repository Details
star Stars 1
call_split Forks 0
navigation Branch main
article Path SKILL.md
More from Creator
luispoliveira
luispoliveira Explore all skills →