Performance Profiler
Tier: POWERFUL
Category: Engineering
Domain: Performance Engineering
Overview
Systematic performance profiling for Node.js, Python, and Go applications. Identifies CPU, memory, and I/O bottlenecks; generates flamegraphs; analyzes bundle sizes; optimizes database queries; detects memory leaks; and runs load tests with k6 and Artillery. Always measures before and after.
Core Capabilities
- CPU profiling — flamegraphs for Node.js, py-spy for Python, pprof for Go
- Memory profiling — heap snapshots, leak detection, GC pressure
- Bundle analysis — webpack-bundle-analyzer, Next.js bundle analyzer
- Database optimization — EXPLAIN ANALYZE, slow query log, N+1 detection
- Load testing — k6 scripts, Artillery scenarios, ramp-up patterns
- Before/after measurement — establish baseline, profile, optimize, verify
When to Use
- App is slow and you don't know where the bottleneck is
- P99 latency exceeds SLA before a release
- Memory usage grows over time (suspected leak)
- Bundle size increased after adding dependencies
- Preparing for a traffic spike (load test before launch)
- Database queries taking >100ms
Quick Start
# Analyze a project for performance risk indicators
python3 scripts/performance_profiler.py /path/to/project
# JSON output for CI integration
python3 scripts/performance_profiler.py /path/to/project --json
# Custom large-file threshold
python3 scripts/performance_profiler.py /path/to/project --large-file-threshold-kb 256
Golden Rule: Measure First
# Establish baseline BEFORE any optimization
# Record: P50, P95, P99 latency | RPS | error rate | memory usage
# Wrong: "I think the N+1 query is slow, let me fix it"
# Right: Profile → confirm bottleneck → fix → measure again → verify improvement
Node.js Profiling
→ See references/profiling-recipes.md for details
Before/After Measurement Template
## Performance Optimization: [What You Fixed]
**Date:** 2026-03-01
**Engineer:** @username
**Ticket:** PROJ-123
### Problem
[1-2 sentences: what was slow, how was it observed]
### Root Cause
[What the profiler revealed]
### Baseline (Before)
| Metric | Value |
|--------|-------|
| P50 latency | 480ms |
| P95 latency | 1,240ms |
| P99 latency | 3,100ms |
| RPS @ 50 VUs | 42 |
| Error rate | 0.8% |
| DB queries/req | 23 (N+1) |
Profiler evidence: [link to flamegraph or screenshot]
### Fix Applied
[What changed — code diff or description]
### After
| Metric | Before | After | Delta |
|--------|--------|-------|-------|
| P50 latency | 480ms | 48ms | -90% |
| P95 latency | 1,240ms | 120ms | -90% |
| P99 latency | 3,100ms | 280ms | -91% |
| RPS @ 50 VUs | 42 | 380 | +804% |
| Error rate | 0.8% | 0% | -100% |
| DB queries/req | 23 | 1 | -96% |
### Verification
Load test run: [link to k6 output]
Optimization Checklist
Quick wins (check these first)
Database
□ Missing indexes on WHERE/ORDER BY columns
□ N+1 queries (check query count per request)
□ Loading all columns when only 2-3 needed (SELECT *)
□ No LIMIT on unbounded queries
□ Missing connection pool (creating new connection per request)
Node.js
□ Sync I/O (fs.readFileSync) in hot path
□ JSON.parse/stringify of large objects in hot loop
□ Missing caching for expensive computations
□ No compression (gzip/brotli) on responses
□ Dependencies loaded in request handler (move to module level)
Bundle
□ Moment.js → dayjs/date-fns
□ Lodash (full) → lodash/function imports
□ Static imports of heavy components → dynamic imports
□ Images not optimized / not using next/image
□ No code splitting on routes
API
□ No pagination on list endpoints
□ No response caching (Cache-Control headers)
□ Serial awaits that could be parallel (Promise.all)
□ Fetching related data in a loop instead of JOIN
Common Pitfalls
- Optimizing without measuring — you'll optimize the wrong thing
- Testing in development — profile against production-like data volumes
- Ignoring P99 — P50 can look fine while P99 is catastrophic
- Premature optimization — fix correctness first, then performance
- Not re-measuring — always verify the fix actually improved things
- Load testing production — use staging with production-size data
Best Practices
- Baseline first, always — record metrics before touching anything
- One change at a time — isolate the variable to confirm causation
- Profile with realistic data — 10 rows in dev, millions in prod — different bottlenecks
- Set performance budgets —
p(95) < 200ms in CI thresholds with k6
- Monitor continuously — add Datadog/Prometheus metrics for key paths
- Cache invalidation strategy — cache aggressively, invalidate precisely
- Document the win — before/after in the PR description motivates the team
1---2name: performance-profiler3description: Systematic performance profiling for Node.js, Python, and Go applications. Identifies CPU, memory, and I/O bottlenecks, generates flamegraphs, analyzes bundle sizes, optimizes database queries, runs load tests with k6 and Artillery. Always measures before and after. Use when investigating a slow endpoint, planning a performance budget, or hunting a memory leak in production.4---56# Performance Profiler78**Tier:** POWERFUL 9**Category:** Engineering 10**Domain:** Performance Engineering 1112---1314## Overview1516Systematic performance profiling for Node.js, Python, and Go applications. Identifies CPU, memory, and I/O bottlenecks; generates flamegraphs; analyzes bundle sizes; optimizes database queries; detects memory leaks; and runs load tests with k6 and Artillery. Always measures before and after.1718## Core Capabilities1920- **CPU profiling** — flamegraphs for Node.js, py-spy for Python, pprof for Go21- **Memory profiling** — heap snapshots, leak detection, GC pressure22- **Bundle analysis** — webpack-bundle-analyzer, Next.js bundle analyzer23- **Database optimization** — EXPLAIN ANALYZE, slow query log, N+1 detection24- **Load testing** — k6 scripts, Artillery scenarios, ramp-up patterns25- **Before/after measurement** — establish baseline, profile, optimize, verify2627---2829## When to Use3031- App is slow and you don't know where the bottleneck is32- P99 latency exceeds SLA before a release33- Memory usage grows over time (suspected leak)34- Bundle size increased after adding dependencies35- Preparing for a traffic spike (load test before launch)36- Database queries taking >100ms3738---3940## Quick Start4142```bash43# Analyze a project for performance risk indicators44python3 scripts/performance_profiler.py /path/to/project4546# JSON output for CI integration47python3 scripts/performance_profiler.py /path/to/project --json4849# Custom large-file threshold50python3 scripts/performance_profiler.py /path/to/project --large-file-threshold-kb 25651```5253---5455## Golden Rule: Measure First5657```bash58# Establish baseline BEFORE any optimization59# Record: P50, P95, P99 latency | RPS | error rate | memory usage6061# Wrong: "I think the N+1 query is slow, let me fix it"62# Right: Profile → confirm bottleneck → fix → measure again → verify improvement63```6465---6667## Node.js Profiling68→ See references/profiling-recipes.md for details6970## Before/After Measurement Template7172```markdown73## Performance Optimization: [What You Fixed]7475**Date:** 2026-03-01 76**Engineer:** @username 77**Ticket:** PROJ-123 7879### Problem80[1-2 sentences: what was slow, how was it observed]8182### Root Cause83[What the profiler revealed]8485### Baseline (Before)86| Metric | Value |87|--------|-------|88| P50 latency | 480ms |89| P95 latency | 1,240ms |90| P99 latency | 3,100ms |91| RPS @ 50 VUs | 42 |92| Error rate | 0.8% |93| DB queries/req | 23 (N+1) |9495Profiler evidence: [link to flamegraph or screenshot]9697### Fix Applied98[What changed — code diff or description]99100### After101| Metric | Before | After | Delta |102|--------|--------|-------|-------|103| P50 latency | 480ms | 48ms | -90% |104| P95 latency | 1,240ms | 120ms | -90% |105| P99 latency | 3,100ms | 280ms | -91% |106| RPS @ 50 VUs | 42 | 380 | +804% |107| Error rate | 0.8% | 0% | -100% |108| DB queries/req | 23 | 1 | -96% |109110### Verification111Load test run: [link to k6 output]112```113114---115116## Optimization Checklist117118### Quick wins (check these first)119120```121Database122□ Missing indexes on WHERE/ORDER BY columns123□ N+1 queries (check query count per request)124□ Loading all columns when only 2-3 needed (SELECT *)125□ No LIMIT on unbounded queries126□ Missing connection pool (creating new connection per request)127128Node.js129□ Sync I/O (fs.readFileSync) in hot path130□ JSON.parse/stringify of large objects in hot loop131□ Missing caching for expensive computations132□ No compression (gzip/brotli) on responses133□ Dependencies loaded in request handler (move to module level)134135Bundle136□ Moment.js → dayjs/date-fns137□ Lodash (full) → lodash/function imports138□ Static imports of heavy components → dynamic imports139□ Images not optimized / not using next/image140□ No code splitting on routes141142API143□ No pagination on list endpoints144□ No response caching (Cache-Control headers)145□ Serial awaits that could be parallel (Promise.all)146□ Fetching related data in a loop instead of JOIN147```148149---150151## Common Pitfalls152153- **Optimizing without measuring** — you'll optimize the wrong thing154- **Testing in development** — profile against production-like data volumes155- **Ignoring P99** — P50 can look fine while P99 is catastrophic156- **Premature optimization** — fix correctness first, then performance157- **Not re-measuring** — always verify the fix actually improved things158- **Load testing production** — use staging with production-size data159160---161162## Best Practices1631641. **Baseline first, always** — record metrics before touching anything1652. **One change at a time** — isolate the variable to confirm causation1663. **Profile with realistic data** — 10 rows in dev, millions in prod — different bottlenecks1674. **Set performance budgets** — `p(95) < 200ms` in CI thresholds with k61685. **Monitor continuously** — add Datadog/Prometheus metrics for key paths1696. **Cache invalidation strategy** — cache aggressively, invalidate precisely1707. **Document the win** — before/after in the PR description motivates the team