---
name: performance-optimization
description: >-
  Identifies and resolves performance bottlenecks through profiling-driven analysis.
  Use when response times are slow, load tests reveal bottlenecks, database queries
  are sluggish, or throughput needs improvement. NOT for security issues, cloud cost
  reduction, or feature development.
allowed-tools:
  - Read
  - Glob
  - Grep
  - Bash
---

## Identity & Scope

**Executor:** either
**Model tier:** sonnet
**Scope:** Application code, database queries, config files, profiling output, load test results.
**Off-limits:** Deploying to production, modifying live databases, running load tests against production without approval.

### Hard Rules
- No credentials in output or git — ever
- No spending money or publishing without explicit user approval
- No deleting files — archive first, 48hr hold
- Report completion to boss via structured output

## Essential Principles

1. **Measure before optimizing** — Profile first, find the actual bottleneck. Guards against: optimizing non-bottleneck code.
2. **Quantify with before/after numbers** — "Feels faster" is not measurement. Guards against: placebo optimizations.
3. **Optimize the bottleneck only** — Improving non-bottleneck code is waste. Guards against: scattered micro-optimizations.
4. **Never sacrifice correctness** — A fast wrong answer is worse than slow right one. Guards against: bugs from aggressive optimization.

## When to Use
- Specific endpoint or operation is slow with measurable latency
- Load testing reveals P95/P99 exceeding SLA
- Database queries taking >100ms in monitoring
- CPU/memory utilization unexpectedly high for workload

## When NOT to Use
- Cloud cost reduction — use cloud-cost-optimization instead
- Security scanning — use security-assessment instead
- Adding features — optimization is for existing code
- Capacity planning — use architecture planning instead

## Rationalizations to Reject

| Shortcut | Why it's wrong |
|----------|----------------|
| "I know the bottleneck without profiling" | Intuition is wrong more than right. Profile first. Always. |
| "Optimize everything at once" | Shotgun optimization obscures what helped. One change, measure, repeat. |
| "Caching will fix it" | Caching adds invalidation complexity. Confirm bottleneck is repeated computation first. |
| "Improvement is obvious, no after-measurement" | Without numbers you can't prove it worked. |

## Workflow

### Phase 1: Profile
**Entry:** Performance problem reported or suspected.
**Actions:**
1. Identify the specific slow operation (not "the whole app").
2. Establish baseline: P50/P95/P99 latency, throughput, resource utilization.
3. Classify bottleneck: CPU / memory / I/O / network / database.
**Exit:** Bottleneck identified with baseline metrics.

### Phase 2: Root Cause
**Entry:** Phase 1 complete.
**Actions:**
1. Trace critical path from entry to bottleneck.
2. For DB: query plans, missing indexes, N+1 patterns.
3. For CPU: hot loops, unnecessary computation, missing memoization.
4. For I/O: synchronous calls, missing connection pooling, unbatched ops.
**Exit:** Root cause documented with specific code locations.

### Phase 3: Recommend
**Entry:** Phase 2 complete.
**Actions:**
1. Propose fixes ordered by expected impact.
2. Estimate improvement per fix (e.g., "index should reduce 450ms to <5ms").
3. Flag any correctness/reliability trade-offs. Separate quick wins from structural changes.
**Exit:** Prioritized fix list with expected improvements.

### Phase 4: Verify
**Entry:** All prior phases complete.
**Actions:**
1. Confirm every recommendation has baseline and expected improvement.
2. Confirm bottleneck classification supported by evidence.
3. If fixes implemented, verify before/after measurements show improvement.
**Exit:** All checks pass — report results to boss/user.

## Output Format

```json
{
  "skill": "performance-optimization",
  "status": "completed",
  "worker": "worker-006",
  "summary": "3 bottlenecks in /api/users. Expected: P95 from 2.3s to ~120ms.",
  "findings": [
    {"item": "N+1 in UserSerializer.get_permissions()", "severity": "critical", "detail": "50 users = 150 queries. Fix: select_related. ~1800ms saved.", "baseline": "P95: 2300ms", "expected_after": "~500ms"},
    {"item": "Missing index on users.organization_id", "severity": "high", "detail": "Full scan on 2.1M rows. Fix: add index. 450ms -> <5ms.", "baseline": "450ms", "expected_after": "<5ms"}
  ],
  "errors": [],
  "elapsed_seconds": 52.6
}
```

**Bad example:** `{"summary": "App is slow", "findings": [{"item": "Add caching", "detail": "Would help."}]}` — No profiling, no baseline, no specific bottleneck, no expected improvement.

## Escalation Triggers

STOP and report to boss when:
- Profiling requires running tools against production
- Bottleneck is in a third-party service you can't modify
- Fix requires schema migration on large production database
- Performance issues may be caused by a security incident
- Fix requires significant architectural changes

Report as: `{"status": "escalated", "reason": "...", "context": "...", "recommendation": "..."}`

## Success Criteria

- [ ] Specific bottleneck(s) identified with classification
- [ ] Baseline metrics recorded
- [ ] Every recommendation has expected improvement estimate
- [ ] Recommendations ordered by impact
- [ ] No correctness sacrificed without explicit warning
- [ ] Output matches JSON format above
