Performance Optimization
Identify and resolve performance bottlenecks through static analysis and design review. Good performance optimization is measurement-driven — identify the bottleneck first, optimize second.
Core Rule
Never optimize without understanding the bottleneck. Random optimization wastes time and often makes things worse. The workflow is always: measure → identify → optimize → verify.
Workflow
Step 1: Understand the Problem
Before touching code, establish baselines:
- What is slow? Specific endpoint, page load, batch job, query?
- How slow? Current latency/throughput numbers (or perceived slowness)
- What's acceptable? Target latency, throughput, or response time
- When did it start? Was it always slow, or is this a regression?
- Under what conditions? Load-dependent, data-size-dependent, time-dependent?
If the user doesn't have measurements, help them instrument first (see Step 2). Optimization without measurement is guessing.
Step 2: Identify the Bottleneck
The bottleneck is almost always in one of these areas. Check in this order (most common first):
- Database queries — N+1 problems, missing indexes, full table scans, unoptimized joins
- External API calls — Sequential calls that could be parallel, no caching of responses
- Algorithmic complexity — O(n²) or worse hiding in loops, nested iterations over large datasets
- Memory usage — Leaks, loading entire datasets into memory, unbounded caches
- Network/I/O — Large payloads, no compression, chatty protocols, missing CDN
- Serialization — Expensive JSON parsing/generation, unnecessary data transformation
- Concurrency issues — Race conditions, lock contention, thread pool exhaustion, async bottlenecks. See references/concurrency.md for patterns and common bugs.
See references/bottleneck-patterns.md for the detailed detection guide.
Step 3: Analyze and Recommend
For each identified bottleneck:
- Explain what the problem is and why it causes slowness
- Quantify the impact (e.g., "This makes 50 DB queries per page load instead of 2")
- Propose a specific fix with expected improvement
- Assess the complexity and risk of the fix
Order recommendations by impact-to-effort ratio. The best optimizations are high impact and low effort.
Step 4: Implement the Fix
Apply one optimization at a time. For each:
- Write or confirm a performance test exists (even a simple timing assertion)
- Apply the change
- Verify the improvement
- Check for regressions (functional tests still pass, other paths not degraded)
Step 5: Verify and Document
After optimization:
- Compare before/after metrics
- Document what was changed and why (this prevents someone from "cleaning up" the optimization later)
- Set up monitoring to alert if performance regresses
Anti-patterns
- Premature optimization: Don't optimize code that runs once at startup or handles 10 requests/day
- Micro-optimization: Don't optimize individual array operations when the real bottleneck is a database query taking 2 seconds
- Caching everything: Caches add complexity and staleness bugs. Cache only what's measured as slow and frequently accessed
- Optimizing the wrong layer: Frontend optimization won't fix a slow API. Database optimization won't fix a slow algorithm
- Sacrificing readability: If the optimization makes the code unmaintainable, it's a bad trade unless the performance gain is critical
Principles Applied
- KISS: The simplest optimization that meets the target wins. Don't build a distributed cache when a database index will do.
- YAGNI: Optimize for current scale, not hypothetical future scale. Document triggers for when to revisit.
- DRY: Centralize caching logic, query optimization, and connection management — don't optimize the same pattern in 10 places.
1---2name: performance-optimization3description: Identify and resolve performance bottlenecks via static analysis — N+1 queries, algorithmic complexity, query optimization, caching, memory leaks, bundle size, connection management. Triggers: this is slow, optimize, performance, N+1, query optimization, caching, bundle size, memory leak, latency, response time, scale, bottleneck.4---56# Performance Optimization78Identify and resolve performance bottlenecks through static analysis and design review. Good performance optimization is measurement-driven — identify the bottleneck first, optimize second.910## Core Rule1112**Never optimize without understanding the bottleneck.** Random optimization wastes time and often makes things worse. The workflow is always: measure → identify → optimize → verify.1314## Workflow1516### Step 1: Understand the Problem1718Before touching code, establish baselines:1920- **What is slow?** Specific endpoint, page load, batch job, query?21- **How slow?** Current latency/throughput numbers (or perceived slowness)22- **What's acceptable?** Target latency, throughput, or response time23- **When did it start?** Was it always slow, or is this a regression?24- **Under what conditions?** Load-dependent, data-size-dependent, time-dependent?2526If the user doesn't have measurements, help them instrument first (see Step 2). Optimization without measurement is guessing.2728### Step 2: Identify the Bottleneck2930The bottleneck is almost always in one of these areas. Check in this order (most common first):31321. **Database queries** — N+1 problems, missing indexes, full table scans, unoptimized joins332. **External API calls** — Sequential calls that could be parallel, no caching of responses343. **Algorithmic complexity** — O(n²) or worse hiding in loops, nested iterations over large datasets354. **Memory usage** — Leaks, loading entire datasets into memory, unbounded caches365. **Network/I/O** — Large payloads, no compression, chatty protocols, missing CDN376. **Serialization** — Expensive JSON parsing/generation, unnecessary data transformation387. **Concurrency issues** — Race conditions, lock contention, thread pool exhaustion, async bottlenecks. See [references/concurrency.md](references/concurrency.md) for patterns and common bugs.3940See [references/bottleneck-patterns.md](references/bottleneck-patterns.md) for the detailed detection guide.4142### Step 3: Analyze and Recommend4344For each identified bottleneck:45461. **Explain** what the problem is and why it causes slowness472. **Quantify** the impact (e.g., "This makes 50 DB queries per page load instead of 2")483. **Propose** a specific fix with expected improvement494. **Assess** the complexity and risk of the fix5051Order recommendations by impact-to-effort ratio. The best optimizations are high impact and low effort.5253### Step 4: Implement the Fix5455Apply one optimization at a time. For each:56571. Write or confirm a performance test exists (even a simple timing assertion)582. Apply the change593. Verify the improvement604. Check for regressions (functional tests still pass, other paths not degraded)6162### Step 5: Verify and Document6364After optimization:65- Compare before/after metrics66- Document what was changed and why (this prevents someone from "cleaning up" the optimization later)67- Set up monitoring to alert if performance regresses6869## Anti-patterns7071- **Premature optimization**: Don't optimize code that runs once at startup or handles 10 requests/day72- **Micro-optimization**: Don't optimize individual array operations when the real bottleneck is a database query taking 2 seconds73- **Caching everything**: Caches add complexity and staleness bugs. Cache only what's measured as slow and frequently accessed74- **Optimizing the wrong layer**: Frontend optimization won't fix a slow API. Database optimization won't fix a slow algorithm75- **Sacrificing readability**: If the optimization makes the code unmaintainable, it's a bad trade unless the performance gain is critical7677## Principles Applied7879- **KISS**: The simplest optimization that meets the target wins. Don't build a distributed cache when a database index will do.80- **YAGNI**: Optimize for current scale, not hypothetical future scale. Document triggers for when to revisit.81- **DRY**: Centralize caching logic, query optimization, and connection management — don't optimize the same pattern in 10 places.