Profiles runtime performance of Node.js, Python, and Go applications. Identifies rendering bottlenecks in React/Next.js, analyzes bundle size and tree-shaking effectiveness, measures API response times and database query performance, and detects memory leaks. Produces actionable optimization recommendations with estimated impact. Activate on: 'slow API', 'performance issue', 'bundle too large', 'memory leak', 'rendering slow', 'profile application', 'optimize performance', 'high latency', 'GC pressure'. NOT for: load testing at scale (use site-reliability-engineer), CI pipeline speed (use ci-cache-optimizer), algorithmic complexity analysis only (use code-architecture).
Install with Codex or Claude Copy this prompt, paste it into Codex, Claude, or another assistant, and let it review the skill page and install it for you.
A direct command skips the review prompt. Inspect the source before running it.
Profiles runtime performance of Node.js, Python, and Go applications. Identifies rendering bottlenecks in React/Next.js, analyzes bundle size and tree-shaking effectiveness, measures API response times and database query performance, and detects memory leaks. Produces actionable optimization recommendations with estimated impact. Activate on: 'slow API', 'performance issue', 'bundle too large', 'memory leak', 'rendering slow', 'profile application', 'optimize performance', 'high latency', 'GC pressure'. NOT for: load testing at scale (use site-reliability-engineer), CI pipeline speed (use ci-cache-optimizer), algorithmic complexity analysis only (use code-architecture).
[{"skill":"observability-apm-expert","reason":"APM provides production telemetry that informs profiling targets"},{"skill":"react-performance-optimizer","reason":"React-specific rendering optimizations after profiling identifies component bottlenecks"},{"skill":"site-reliability-engineer","reason":"SRE owns production performance SLOs that profiling helps meet"},{"skill":"data-pipeline-engineer","reason":"Database query optimization often requires pipeline-level understanding"}]
Performance Profiler
Measures, diagnoses, and optimizes application performance across the full stack. This skill does not guess -- it profiles first, then recommends changes with estimated impact.
Activation Triggers
Activate on: "slow API", "performance issue", "bundle too large", "memory leak", "rendering slow", "profile application", "optimize performance", "high latency", "GC pressure", "p99 latency", "TTFB too high", "LCP regression", "why is this slow"
NOT for: Load testing at scale --> site-reliability-engineer | CI pipeline speed --> ci-cache-optimizer | Algorithmic theory --> code-architecture | React-only optimization --> react-performance-optimizer
Core Capabilities
Profile Node.js applications with V8 CPU profiler and heap snapshots
Profile Python applications with cProfile, py-spy, and memory_profiler
Profile Go applications with pprof (CPU, memory, goroutine, block)
Event loop delay > 50ms at p99 means synchronous work is blocking. Common culprits: JSON.parse on large payloads, synchronous file I/O, CPU-intensive computation, regex backtracking.
Python Profiling
CPU Profiling
# cProfile (built-in, low overhead)
python -m cProfile -s cumulative app.py
# py-spy (sampling profiler, attaches to running process)
py-spy record -o profile.svg -- python app.py
py-spy top --pid <PID> # live view, no restart needed# line_profiler for function-level detail# Add @profile decorator to functions of interest
kernprof -l -v app.py
Memory Profiling
# memory_profiler for line-by-line memory usage# Add @profile decorator to suspect functions
python -m memory_profiler app.py
# tracemalloc (built-in, tracks allocations)
python -c "
import tracemalloc
tracemalloc.start()
# ... run your code ...
snapshot = tracemalloc.take_snapshot()
for stat in snapshot.statistics('lineno')[:10]:
print(stat)
"# objgraph for reference tracking
python -c "
import objgraph
objgraph.show_most_common_types(limit=20)
objgraph.show_growth()
"
Django/Flask Request Profiling
# Django: django-silk for per-request profiling# Add to INSTALLED_APPS and MIDDLEWARE, then visit /silk/# Flask: flask-profiler or Werkzeug profiler middleware# app.wsgi_app = ProfilerMiddleware(app.wsgi_app, restrictions=[30])# General: py-spy against running server
py-spy record -o profile.svg --pid $(pgrep -f "gunicorn")
Go Profiling
# CPU profile
go test -cpuprofile cpu.prof -bench .
go tool pprof cpu.prof
# Memory profile
go test -memprofile mem.prof -bench .
go tool pprof mem.prof
# HTTP pprof (add to running server)# import _ "net/http/pprof"# then: go tool pprof http://localhost:6060/debug/pprof/profile?seconds=30# Goroutine profile (detect goroutine leaks)
go tool pprof http://localhost:6060/debug/pprof/goroutine
# Block profile (detect lock contention)# runtime.SetBlockProfileRate(1) in code
go tool pprof http://localhost:6060/debug/pprof/block
Go-specific patterns:
Goroutine leak: goroutine count grows monotonically. Check runtime.NumGoroutine() over time.
Excessive allocation: go test -benchmem shows allocs/op. Target zero-alloc hot paths.
Lock contention: block profile shows time spent waiting on mutexes. Consider sync.RWMutex or lock-free alternatives.
React / Next.js Performance
Component Rendering
// React DevTools Profiler (browser extension)// Record → identify components re-rendering unnecessarily// Why Did You Render (development only)// npm install @welldone-software/why-did-you-renderimportReactfrom'react';
if (process.env.NODE_ENV === 'development') {
const whyDidYouRender = require('@welldone-software/why-did-you-render');
whyDidYouRender(React, { trackAllPureComponents: true });
}
Common React performance issues and fixes:
Problem
Detection
Fix
Impact
Unnecessary re-renders
React Profiler shows renders without prop changes
React.memo, useMemo, useCallback
High
Large component trees
Profiler shows deep re-render cascades
Split components, lift state down
High
Expensive computations in render
Flamegraph shows CPU time in render
useMemo with correct deps
Medium
Context over-triggering
All consumers re-render on any context change
Split contexts by update frequency
High
Missing list keys or wrong keys
Warning in console + full list re-render
Stable, unique keys (not array index)
Medium
Unoptimized images
LCP regression, large layout shifts
next/image with proper sizing
High
Next.js Specific
# Analyze bundle with @next/bundle-analyzer
ANALYZE=true next build
# Check route segment sizes
next build # Look at the "Size" and "First Load JS" columns# Trace server-side rendering time
NEXT_OTEL_VERBOSE=1 next dev
Next.js performance targets:
Metric
Good
Needs Work
Critical
First Load JS (per route)
< 100 KB
100-200 KB
> 200 KB
TTFB
< 200ms
200-500ms
> 500ms
LCP
< 2.5s
2.5-4.0s
> 4.0s
CLS
< 0.1
0.1-0.25
> 0.25
INP
< 200ms
200-500ms
> 500ms
Bundle Size Analysis
# Webpack bundle analyzer
npx webpack-bundle-analyzer dist/stats.json
# Next.js specific
ANALYZE=true npx next build
# Vite: rollup-plugin-visualizer# Add to vite.config.ts plugins array# Source map explorer (works with any bundler)
npx source-map-explorer dist/**/*.js
# Check individual package sizes
npx bundlephobia <package-name>
# or use https://bundlephobia.com
Bundle optimization checklist:
Tree-shaking verification: Import { specific } not import *. Check if dead code is actually eliminated.
Dynamic imports: React.lazy() or next/dynamic for routes and heavy components.
Package alternatives: Replace moment with date-fns (87 KB --> 12 KB tree-shaken). Replace lodash with lodash-es or individual imports.
Duplicate packages: Check for multiple versions of the same package in bundle. npm ls <package> to find duplicates.
Polyfill audit: Modern browsers do not need core-js for most features. Check browserslist config.
Image formats: WebP/AVIF instead of PNG/JPEG. Use next/image or sharp for optimization.
Database Query Performance
PostgreSQL
-- Find slow queries (requires pg_stat_statements)SELECT query, calls, mean_exec_time, total_exec_time
FROM pg_stat_statements
ORDERBY mean_exec_time DESC
LIMIT 20;
-- Explain a slow query
EXPLAIN (ANALYZE, BUFFERS, FORMAT TEXT) SELECT ...;
-- Check index usageSELECT schemaname, tablename, indexname, idx_scan, idx_tup_read
FROM pg_stat_user_indexes
WHERE idx_scan =0-- unused indexesORDERBY pg_relation_size(indexrelid) DESC;
-- Find missing indexes (sequential scans on large tables)SELECT relname, seq_scan, seq_tup_read, idx_scan
FROM pg_stat_user_tables
WHERE seq_scan >100AND seq_tup_read >10000ORDERBY seq_tup_read DESC;
Query Optimization Decision Tree
Query slow?
├── Full table scan?
│ ├── Yes → Add index on WHERE/JOIN columns
│ └── No → Index exists but not used?
│ ├── Yes → Check selectivity, ANALYZE table, check data types match
│ └── No → Move to join analysis
├── Joining many tables?
│ ├── Yes → Check join order, ensure foreign keys indexed
│ └── No → Returning too many rows?
│ ├── Yes → Add LIMIT, implement pagination
│ └── No → Complex aggregation?
│ ├── Yes → Consider materialized view
│ └── No → Profile application-side processing
Symptom: Optimizing code that accounts for 0.1% of total execution time
Why wrong: Maximum possible improvement is 0.1%, time wasted
Fix: Profile first. Optimize the top bottleneck, re-profile, repeat. Amdahl's Law applies.
2. Micro-benchmarks in Isolation
Symptom: Benchmarking a single function in a loop, declaring it "fast enough"
Why wrong: Real performance depends on context -- cache behavior, GC pressure, concurrent load
Fix: Profile under realistic workloads. Use production-like data volumes.
3. Caching Without Measurement
Symptom: Adding Redis/Memcached to every slow endpoint
Why wrong: If the bottleneck is computation not data access, caching helps nothing. Cache invalidation adds complexity.
Fix: Measure whether the slow part is data fetching, computation, or serialization. Cache only if data fetching dominates.
4. Bundle Size Whack-a-Mole
Symptom: Removing one large dependency, adding another without checking
Fix: Track bundle size in CI. Set a budget. Fail the build if budget exceeded.
5. Ignoring GC Pressure
Symptom: Profiling shows fast execution but high p99 latency
Why wrong: GC pauses cause latency spikes invisible to CPU profiles
Fix: Monitor GC with --trace-gc. Reduce allocation rate in hot paths. Use object pooling for high-churn objects.
6. Optimizing Without a Budget
Symptom: "Make it faster" with no target
Why wrong: No definition of done, infinite yak-shaving
Fix: Set specific targets: "p99 < 200ms" or "bundle < 150KB". Stop when met.
Set aggressive timeouts so external slowness does not cascade
Quality Checklist
[ ] Baseline performance measured with numbers (not "it feels slow")
[ ] Bottleneck identified through profiling (not guessing)
[ ] Optimization targets set with specific metrics and thresholds
[ ] Fix addresses the actual bottleneck, not a secondary concern
[ ] Performance measured after fix with same methodology as baseline
[ ] No regressions introduced in other areas (full test suite passes)
[ ] Memory profile shows no new leaks introduced
[ ] Bundle size delta documented if frontend changes made
[ ] Database query changes validated with EXPLAIN ANALYZE
[ ] Improvement quantified: "p99 reduced from 850ms to 120ms" not "faster"
[ ] Performance budget established for ongoing monitoring
[ ] Findings documented for future reference