performance-optimization
Systematic approach to identifying and resolving performance bottlenecks in software systems. Use when application response times exceed SLAs, resource usage is high, before scaling infrastructure, during performance testing, or when users report slowness.
Install
mkdir -p .claude/skills/performance-optimization-zacharyluz && curl -L -o skill.zip "https://agentskills.codes/api/skills/download/14958" && unzip -o skill.zip -d .claude/skills/performance-optimization-zacharyluz && rm skill.zipInstalls to .claude/skills/performance-optimization-zacharyluz
Activation
This is the description your AI agent reads to decide when to run this skill — the better it matches your request, the more reliably it fires.
Systematic approach to identifying and resolving performance bottlenecks in software systems. Use when application response times exceed SLAs, resource usage is high, before scaling infrastructure, during performance testing, or when users report slowness.About this skill
Performance Optimization Skill
Core Principle
Measure first, optimize second. Never guess at performance.
Performance optimization without measurement is guesswork. Every optimization must:
- Start with profiling — Identify actual bottlenecks, not assumed ones
- Establish baselines — Know current performance before changing anything
- Measure impact — Verify optimizations actually improve performance
- Avoid premature optimization — Optimize based on real-world needs, not theoretical concerns
- Consider trade-offs — Every optimization has costs (complexity, maintainability, development time)
When to Optimize
Good Times to Optimize
✅ SLA violations — Response times consistently exceed service level agreements ✅ High resource usage — CPU, memory, or I/O consistently at capacity ✅ Before scaling — Optimize code before throwing more hardware at the problem ✅ User complaints — Real users reporting slowness or timeouts ✅ Performance testing — During regular performance validation cycles ✅ After profiling — When bottlenecks are identified and measured
Bad Times to Optimize
❌ Without profiling — Don't optimize without knowing where the bottleneck is ❌ Premature optimization — Don't optimize before you have performance problems ❌ During feature development — Build it first, optimize later ❌ Without tests — Can't verify correctness after optimization ❌ Based on hunches — "I think this is slow" without measurement
Performance Profiling
Profiling Categories
1. CPU Profiling
What it measures: Where CPU time is spent in your code
When to use:
- High CPU usage
- Slow computation or algorithms
- Long request processing times
Tools by language:
Python:
# cProfile - built-in profiler
python -m cProfile -s cumulative script.py
# py-spy - sampling profiler (no code changes needed)
py-spy record -o profile.svg -- python script.py
# line_profiler - line-by-line profiling
kernprof -l -v script.py
JavaScript/Node.js:
# Chrome DevTools
node --inspect script.js
# Open chrome://inspect
# clinic.js - Node.js performance profiling
clinic doctor -- node script.js
clinic flame -- node script.js
# Built-in profiler
node --prof script.js
node --prof-process isolate-*.log
Go:
# pprof - built-in profiler
go test -cpuprofile=cpu.prof -bench=.
go tool pprof cpu.prof
# In production with net/http/pprof
import _ "net/http/pprof"
# Access http://localhost:6060/debug/pprof/
Rust:
# cargo flamegraph
cargo install flamegraph
cargo flamegraph
# perf (Linux)
perf record --call-graph=dwarf ./target/release/app
perf report
Java:
# JProfiler, VisualVM, or async-profiler
java -agentpath:/path/to/libasyncProfiler.so=start,file=profile.html -jar app.jar
2. Memory Profiling
What it measures: Memory allocation, usage, and leaks
When to use:
- High memory consumption
- Out of memory errors
- Memory leaks (growing memory over time)
- Garbage collection pressure
Tools by language:
Python:
# memory_profiler
pip install memory_profiler
python -m memory_profiler script.py
# memray - modern memory profiler
pip install memray
memray run script.py
memray flamegraph output.bin
# objgraph - find memory leaks
import objgraph
objgraph.show_most_common_types()
JavaScript/Node.js:
# Chrome DevTools heap snapshot
node --inspect script.js
# clinic.js heapprofiler
clinic heapprofiler -- node script.js
# node-memwatch
npm install @airbnb/node-memwatch
Go:
# Memory profiling with pprof
go test -memprofile=mem.prof -bench=.
go tool pprof mem.prof
# Heap dump
import _ "net/http/pprof"
curl http://localhost:6060/debug/pprof/heap > heap.prof
go tool pprof heap.prof
Rust:
# Valgrind massif
valgrind --tool=massif ./target/release/app
ms_print massif.out.*
# heaptrack
heaptrack ./target/release/app
3. I/O Profiling
What it measures: Disk and network I/O operations
When to use:
- Slow file operations
- Network latency
- Database query performance
- API call delays
Tools:
# strace (Linux) - system call tracing
strace -c python script.py # Count calls
strace -T python script.py # Time each call
# iotop (Linux) - disk I/O monitoring
sudo iotop -o # Only show processes doing I/O
# tcpdump - network traffic analysis
sudo tcpdump -i any -w capture.pcap
# Wireshark - GUI network analysis
wireshark capture.pcap
4. Database Profiling
What it measures: Query performance, connection usage, lock contention
PostgreSQL:
-- Enable query logging
ALTER SYSTEM SET log_min_duration_statement = 100; -- Log queries > 100ms
-- Analyze query plan
EXPLAIN ANALYZE SELECT * FROM users WHERE email = '[email protected]';
-- Find slow queries
SELECT query, mean_exec_time, calls
FROM pg_stat_statements
ORDER BY mean_exec_time DESC
LIMIT 10;
-- Check index usage
SELECT schemaname, tablename, indexname, idx_scan
FROM pg_stat_user_indexes
ORDER BY idx_scan;
MySQL:
-- Enable slow query log
SET GLOBAL slow_query_log = 'ON';
SET GLOBAL long_query_time = 0.1; -- 100ms
-- Analyze query
EXPLAIN SELECT * FROM users WHERE email = '[email protected]';
-- Show running queries
SHOW FULL PROCESSLIST;
MongoDB:
// Enable profiling
db.setProfilingLevel(1, { slowms: 100 });
// Analyze query
db.users.find({ email: '[email protected]' }).explain("executionStats");
// View slow queries
db.system.profile.find().sort({ ts: -1 }).limit(10);
5. Frontend Profiling
What it measures: Rendering, JavaScript execution, bundle size, network requests
Tools:
Chrome DevTools:
// Performance tab - record timeline
// Network tab - analyze requests
// Coverage tab - find unused code
// Lighthouse - comprehensive audit
Web Vitals:
// Core Web Vitals monitoring
import { getCLS, getFID, getLCP } from 'web-vitals';
getCLS(console.log); // Cumulative Layout Shift
getFID(console.log); // First Input Delay
getLCP(console.log); // Largest Contentful Paint
Bundle analysis:
# webpack-bundle-analyzer
npm install --save-dev webpack-bundle-analyzer
npx webpack-bundle-analyzer dist/stats.json
# source-map-explorer
npm install -g source-map-explorer
source-map-explorer bundle.js bundle.js.map
Optimization Techniques by Layer
1. Algorithm and Data Structure Optimization
Before (O(n²) - inefficient):
def find_duplicates(items):
duplicates = []
for i in range(len(items)):
for j in range(i + 1, len(items)):
if items[i] == items[j] and items[i] not in duplicates:
duplicates.append(items[i])
return duplicates
# O(n²) time complexity
After (O(n) - efficient):
def find_duplicates(items):
seen = set()
duplicates = set()
for item in items:
if item in seen:
duplicates.add(item)
seen.add(item)
return list(duplicates)
# O(n) time complexity, much faster for large lists
Key principle: Choose the right data structure for the problem
- Lists for ordered data, O(n) search
- Sets for uniqueness, O(1) search
- Dicts for key-value lookups, O(1) access
- Heaps for priority queues
- Trees for hierarchical data
2. Database Optimization
Add Missing Indexes
Before (slow full table scan):
-- Query without index
SELECT * FROM orders WHERE user_id = 12345 AND status = 'pending';
-- EXPLAIN shows: Seq Scan on orders (cost=0.00..1500.00 rows=100)
After (fast index scan):
-- Add composite index
CREATE INDEX idx_orders_user_status ON orders(user_id, status);
-- Now: Index Scan using idx_orders_user_status (cost=0.43..12.50 rows=100)
-- 100x+ faster!
Fix N+1 Query Problem
Before (N+1 queries - extremely slow):
# 1 query to get posts
posts = Post.query.all()
# N queries - one per post to get author
for post in posts:
print(f"{post.title} by {post.author.name}") # Separate query each time!
# 1 + N queries (if 100 posts = 101 queries)
After (2 queries with join - fast):
# Single query with join
posts = Post.query.options(joinedload(Post.author)).all()
for post in posts:
print(f"{post.title} by {post.author.name}") # No additional queries
# Only 2 queries (or 1 with proper join)
Batch Operations
Before (slow - many round trips):
for user_id in user_ids:
db.execute("UPDATE users SET active = true WHERE id = %s", (user_id,))
# 1000 users = 1000 database round trips
After (fast - single batch operation):
db.execute(
"UPDATE users SET active = true WHERE id = ANY(%s)",
(user_ids,)
)
# 1 database round trip
Connection Pooling
Before (creating connection each time - slow):
def get_user(user_id):
conn = psycopg2.connect(DATABASE_URL) # New connection every time!
cursor = conn.cursor()
cursor.execute("SELECT * FROM users WHERE id = %s", (user_id,))
user = cursor.fetchone()
conn.close()
return user
After (connection pool - fast):
from psycopg2 import pool
# Create connection pool at startup
connection_pool = pool.SimpleConnectionPool(
minconn=1,
maxconn=20,
dsn=DATABASE_URL
)
def get_user(user_id):
conn = connection_pool.getconn() # Reuse existing connection
try:
cursor = conn.cursor()
cursor.execute("SELECT * FROM users WHERE id = %s", (user_id,))
return cursor.fetchone()
finally:
connection_pool.putconn(conn) # Return to pool
3. Network Optimization
Compression
Before (large uncompressed responses):
// Express without compression
app.get('/api/data', (req, res) => {
res.json(largeDataObject); // 500KB uncompresse
---
*Content truncated.*