Optimizing Performance

Learn how to identify and fix performance bottlenecks with ClaudeKit - from profiling and analysis to implementation of caching, database optimization, and code improvements.

Overview

Goal: Identify and resolve performance bottlenecks systematically Time: 30-60 minutes (vs 4-12 hours manually) Agents Used: debugger, code-reviewer, tester Commands: /debug, /cook, /test, /fix:hard

Prerequisites

  • Application with performance issues
  • Monitoring/profiling tools installed
  • Performance baseline metrics
  • Test data representative of production

Performance Targets

MetricGoodAcceptablePoor
API Response Time<200ms200-500ms>500ms
Page Load Time<2s2-4s>4s
Database Query<50ms50-200ms>200ms
Memory Usage<512MB512MB-2GB>2GB
CPU Usage<30%30-70%>70%

Step-by-Step Workflow

Step 1: Identify Performance Issues

Start by profiling your application:

# Run performance analysis
/debug [analyze application performance and identify bottlenecks]

Analysis output:

Performance Analysis Report

šŸ”“ Critical Issues (3)

1. Database Query Performance
   Location: src/users/service.js:23
   Issue: N+1 query problem
   Impact: 2,847ms per request
   Queries: 156 individual queries
   Recommendation: Use eager loading

2. Unoptimized Images
   Location: public/uploads/
   Issue: Large image sizes
   Impact: 3.2s additional load time
   Total: 12.4MB transferred
   Recommendation: Image optimization + CDN

3. Missing Cache Layer
   Location: src/products/service.js
   Issue: Repeated expensive operations
   Impact: 95% cache miss rate
   Recommendation: Implement Redis caching

🟔 Warning Issues (5)

4. Inefficient Algorithm
   Location: src/search/index.js:45
   Issue: O(n²) complexity
   Impact: 523ms for 1000 items
   Recommendation: Use hash map (O(n))

5. Blocking Operations
   Location: src/emails/send.js:12
   Issue: Synchronous email sending
   Impact: 890ms blocking
   Recommendation: Use queue (Bull/Redis)

6. Large Bundle Size
   Location: frontend/dist/
   Issue: 4.2MB JavaScript bundle
   Impact: 6s parse time on mobile
   Recommendation: Code splitting

7. No Compression
   Issue: Missing gzip/brotli
   Impact: 2.8x larger transfers
   Recommendation: Enable compression

8. Memory Leaks
   Location: src/websocket/handler.js
   Issue: Event listeners not removed
   Impact: 125MB/hour growth
   Recommendation: Cleanup on disconnect

Performance Score: 34/100 (Poor)
Load Time: 8.2s (Target: <2s)
Time to Interactive: 12.4s (Target: <3.5s)

Step 2: Fix Database Performance

N+1 Query Problem

/cook [fix N+1 query problem in user service with eager loading]

Implementation:

[1/4] Analyzing queries...
  āœ“ Identified 156 individual queries
  āœ“ Should be 1 query with joins

Before:
const users = await User.findAll();
for (const user of users) {
  user.posts = await Post.findAll({ userId: user.id }); // N queries
}

After:
const users = await User.findAll({
  include: [{ model: Post }] // 1 query with JOIN
});

[2/4] Implementing fix...
  āœ“ Added eager loading
  āœ“ Optimized includes
  āœ“ Added select to limit fields

[3/4] Testing...
  āœ“ Query count: 156 → 1
  āœ“ Response time: 2,847ms → 87ms
  āœ“ 97% improvement

[4/4] Documentation...
  āœ“ Added performance notes

āœ… N+1 problem fixed

Add Database Indexes

/cook [add database indexes for frequently queried fields]

Implementation:

[1/3] Analyzing query patterns...
  āœ“ Identified slow queries
  āœ“ Found missing indexes

Indexes to add:
- users.email (unique)
- posts.userId (foreign key)
- posts.status (filter)
- posts.createdAt (sorting)
- products.categoryId (foreign key)
- products.price (range queries)

[2/3] Creating indexes...
  āœ“ Generated migration
  āœ“ Composite indexes for complex queries
  āœ“ Partial indexes for filtered queries

[3/3] Testing...
  āœ“ Query performance improved:
    - User lookup: 234ms → 3ms
    - Post filtering: 567ms → 12ms
    - Product search: 892ms → 34ms

āœ… Indexes added

Query Optimization

/cook [optimize database queries to reduce execution time]

Step 3: Implement Caching

Redis Cache

/cook [implement Redis caching for frequently accessed data]

Implementation:

[1/5] Setting up Redis...
  āœ“ Installed Redis client
  āœ“ Configuration added
  āœ“ Connection pool setup

[2/5] Cache strategy...
  āœ“ Cache-aside pattern
  āœ“ Write-through for updates
  āœ“ TTL configuration

[3/5] Implementing cache...
  āœ“ User data (TTL: 1 hour)
  āœ“ Product catalog (TTL: 15 min)
  āœ“ Search results (TTL: 5 min)
  āœ“ API responses (TTL: 1 min)

[4/5] Cache invalidation...
  āœ“ On update operations
  āœ“ On delete operations
  āœ“ Manual invalidation API

[5/5] Testing...
  āœ“ Cache hit rate: 0% → 87%
  āœ“ Response time: 456ms → 23ms
  āœ“ Database load: -76%

āœ… Redis caching implemented

Performance improvement:
- Average response: 95% faster
- Database queries: 76% reduction
- Server load: 64% reduction

In-Memory Cache

/cook [add in-memory LRU cache for hot data]

CDN Integration

/cook [integrate CloudFlare CDN for static assets]

Step 4: Optimize Frontend

Code Splitting

/cook [implement code splitting and lazy loading]

Implementation:

[1/4] Analyzing bundle...
  āœ“ Current size: 4.2MB
  āœ“ Identified heavy modules
  āœ“ Found unused dependencies

Heavy modules:
- moment.js: 287KB (use date-fns instead)
- lodash: 531KB (use individual imports)
- chart.js: 456KB (lazy load)

[2/4] Code splitting...
  āœ“ Route-based splitting
  āœ“ Component lazy loading
  āœ“ Vendor chunk optimization

[3/4] Tree shaking...
  āœ“ Removed unused code
  āœ“ Optimized imports
  āœ“ Replaced heavy libraries

[4/4] Results...
  āœ“ Bundle size: 4.2MB → 687KB (84% reduction)
  āœ“ Initial load: 6s → 1.2s
  āœ“ Time to interactive: 12.4s → 2.8s

āœ… Frontend optimized

Image Optimization

/cook [optimize images with compression and lazy loading]

Implementation:

[1/4] Image analysis...
  āœ“ Total images: 342
  āœ“ Total size: 12.4MB
  āœ“ Average size: 36KB

[2/4] Optimization...
  āœ“ Convert to WebP format
  āœ“ Compress with quality 85
  āœ“ Generate responsive sizes
  āœ“ Add lazy loading

[3/4] Implementation...
  āœ“ Picture element with fallbacks
  āœ“ Intersection Observer for lazy load
  āœ“ Placeholder images

[4/4] Results...
  āœ“ Image size: 12.4MB → 2.1MB (83% reduction)
  āœ“ Load time: 3.2s → 0.6s
  āœ“ Bandwidth: -10.3MB per page

āœ… Images optimized

Bundle Compression

/cook [enable gzip and brotli compression]

Step 5: Optimize Algorithms

Replace Inefficient Algorithm

/cook [replace O(n²) algorithm with O(n) hash map solution]

Before (O(n²) - 523ms):

function findDuplicates(items) {
  const duplicates = [];
  for (let i = 0; i < items.length; i++) {
    for (let j = i + 1; j < items.length; j++) {
      if (items[i] === items[j]) {
        duplicates.push(items[i]);
      }
    }
  }
  return duplicates;
}

After (O(n) - 4ms):

function findDuplicates(items) {
  const seen = new Set();
  const duplicates = new Set();

  for (const item of items) {
    if (seen.has(item)) {
      duplicates.add(item);
    } else {
      seen.add(item);
    }
  }

  return Array.from(duplicates);
}

Result: 99.2% faster (523ms → 4ms)

Step 6: Async Operations

Background Jobs

/cook [move email sending to background queue with Bull]

Implementation:

[1/4] Setting up Bull queue...
  āœ“ Redis queue configured
  āœ“ Worker processes setup
  āœ“ Job processing logic

[2/4] Moving operations to queue...
  āœ“ Email sending (was 890ms blocking)
  āœ“ Report generation (was 2.3s blocking)
  āœ“ Image processing (was 1.2s blocking)

[3/4] Implementing retry logic...
  āœ“ Automatic retry on failure
  āœ“ Exponential backoff
  āœ“ Dead letter queue

[4/4] Results...
  āœ“ API response: 890ms → 45ms
  āœ“ Non-blocking operations
  āœ“ Better error handling

āœ… Background jobs implemented

Parallel Processing

/cook [process multiple operations in parallel instead of sequential]

Step 7: Database Connection Pool

/cook [optimize database connection pooling]

Configuration:

// Before: Default settings
pool: {
  max: 5,
  min: 0,
  idle: 10000
}

// After: Optimized
pool: {
  max: 20,          // More connections
  min: 5,           // Keep minimum ready
  idle: 30000,      // Longer idle time
  acquire: 60000,   // Longer acquire timeout
  evict: 1000       // Cleanup interval
}

Result: 45% faster during peak load

Step 8: API Rate Limiting & Throttling

/cook [implement intelligent rate limiting and request throttling]

Step 9: Memory Optimization

Fix Memory Leaks

/fix:hard [fix memory leak in WebSocket handler]

Implementation:

[1/4] Identifying leak...
  āœ“ Memory growing 125MB/hour
  āœ“ Event listeners not cleaned up
  āœ“ Socket references retained

[2/4] Implementing fixes...
  āœ“ Remove event listeners on disconnect
  āœ“ Clear socket references
  āœ“ Implement cleanup function

[3/4] Memory management...
  āœ“ WeakMap for temporary data
  āœ“ Clear timers on disconnect
  āœ“ Garbage collection hints

[4/4] Testing...
  āœ“ 24-hour test: stable memory
  āœ“ 1000 connections: no growth
  āœ“ Stress test: passed

āœ… Memory leak fixed

Reduce Memory Usage

/cook [optimize memory usage by using streams for large data]

Step 10: Monitoring & Profiling

/cook [implement performance monitoring with metrics and alerts]

Monitoring setup:

āœ“ Response time tracking
āœ“ Database query monitoring
āœ“ Memory usage alerts
āœ“ CPU usage tracking
āœ“ Error rate monitoring
āœ“ Cache hit rate metrics
āœ“ Custom business metrics
āœ“ Real-user monitoring (RUM)

Alerts configured:
- Response time >500ms
- Error rate >1%
- Memory usage >80%
- CPU usage >75%
- Cache hit rate <70%

Step 11: Load Testing

/test

Performance test results:

Load Test Report (1000 concurrent users)

Before optimization:
- Avg response time: 2,847ms
- 95th percentile: 5,234ms
- Requests/sec: 23
- Error rate: 12.4%
- Failed requests: 124/1000

After optimization:
- Avg response time: 87ms (97% faster)
- 95th percentile: 156ms (97% faster)
- Requests/sec: 892 (38x more)
- Error rate: 0.1%
- Failed requests: 1/1000

Database:
- Query time: 234ms → 8ms (97% faster)
- Queries per request: 156 → 1
- Connection pool usage: 95% → 34%

Memory:
- Usage: 2.1GB → 487MB (77% reduction)
- Leak rate: 125MB/hour → 0MB/hour
- GC pauses: 89/hour → 12/hour

Frontend:
- Bundle size: 4.2MB → 687KB (84% smaller)
- Load time: 8.2s → 1.2s (85% faster)
- Time to interactive: 12.4s → 2.8s (77% faster)

Overall Performance Score: 34/100 → 94/100

āœ… All performance targets met

Complete Example: Slow E-Commerce API

Initial Issues

Performance problems:
- Product listing: 4.2s response time
- Search: 6.8s with 1000 products
- Cart update: 1.8s
- Checkout: 3.4s
- Homepage: 9.2s load time
- High database load: 89% CPU

Optimization Steps

# 1. Profile application
/debug [analyze e-commerce API performance]

# 2. Database optimization
/cook [fix N+1 queries and add indexes]
/cook [optimize product search queries]

# 3. Caching
/cook [implement Redis caching for products and categories]
/cook [add query result caching]

# 4. Frontend optimization
/cook [implement code splitting and lazy loading]
/cook [optimize product images with WebP and lazy loading]

# 5. API optimization
/cook [move image processing to background queue]
/cook [implement response compression]

# 6. Algorithm optimization
/cook [optimize search algorithm with inverted index]

# 7. Test improvements
/test

# 8. Monitor in production
/cook [set up performance monitoring with alerts]

Results

After optimization (1 hour work):

Product listing: 4.2s → 124ms (97% faster)
Search: 6.8s → 89ms (99% faster)
Cart update: 1.8s → 34ms (98% faster)
Checkout: 3.4s → 187ms (95% faster)
Homepage: 9.2s → 1.4s (85% faster)
Database CPU: 89% → 23%

Customer impact:
- 94% faster page loads
- 10x more concurrent users
- 87% lower server costs
- 45% increase in conversions

Time Comparison

Manual optimization: 8-16 hours

  • Profiling: 1-2 hours
  • Database optimization: 2-3 hours
  • Caching: 2-3 hours
  • Frontend: 2-4 hours
  • Testing: 1-2 hours
  • Debugging: 1-2 hours

With ClaudeKit: 58 minutes

  • Profiling: 8 minutes
  • Database: 15 minutes
  • Caching: 12 minutes
  • Frontend: 18 minutes
  • Testing: 5 minutes

Time saved: 7-15 hours (88% faster)

Performance Optimization Patterns

Pattern 1: Progressive Enhancement

/cook [implement progressive enhancement for slow connections]

Pattern 2: Predictive Prefetching

/cook [add predictive prefetching for likely user actions]

Pattern 3: Service Worker Caching

/cook [implement service worker for offline-first experience]

Pattern 4: Database Read Replicas

/cook [set up database read replicas for scaling reads]

Best Practices

1. Measure First

Always profile before optimizing:

āœ… Profile → Identify → Fix → Measure
āŒ Guess → Optimize → Hope

2. Focus on Biggest Impact

Optimize high-impact issues first:

Priority order:
1. Critical path operations
2. High-frequency operations
3. User-facing operations
4. Background operations

3. Cache Aggressively

But invalidate correctly:

// Cache layers
1. Browser cache (static assets)
2. CDN cache (global content)
3. Application cache (Redis)
4. Database query cache
5. Result memoization

4. Use Appropriate Data Structures

āœ… Hash map for lookups: O(1)
āœ… Set for uniqueness: O(1)
āœ… Binary search: O(log n)

āŒ Array loops: O(n)
āŒ Nested loops: O(n²)

5. Monitor Continuously

/cook [implement continuous performance monitoring]

Troubleshooting

Issue: Still Slow After Optimization

Solution:

# Re-profile
/debug [deep performance analysis with detailed metrics]

# Check for new bottlenecks
# Optimize further

Issue: Cache Not Hitting

Solution:

/fix:fast [Redis cache hit rate below 50%]

Issue: Memory Still Growing

Solution:

/fix:hard [memory still growing despite fixes]

Issue: Database Timeout

Solution:

/cook [increase connection pool and optimize slow queries]

Performance Checklist

Backend:
āœ“ Database queries optimized
āœ“ Indexes on frequently queried fields
āœ“ N+1 queries eliminated
āœ“ Caching implemented (Redis)
āœ“ Connection pooling optimized
āœ“ Background jobs for slow operations
āœ“ API response compression
āœ“ Rate limiting configured

Frontend:
āœ“ Code splitting implemented
āœ“ Lazy loading for routes
āœ“ Images optimized (WebP, lazy load)
āœ“ Bundle size minimized
āœ“ Tree shaking enabled
āœ“ CDN for static assets
āœ“ Service worker caching
āœ“ Critical CSS inlined

Infrastructure:
āœ“ Load balancing configured
āœ“ Auto-scaling enabled
āœ“ CDN integration
āœ“ Database read replicas
āœ“ Monitoring and alerts
āœ“ Performance budgets set
āœ“ Regular load testing

Metrics:
āœ“ Response time <200ms
āœ“ Page load <2s
āœ“ Time to interactive <3.5s
āœ“ Cache hit rate >80%
āœ“ Error rate <0.1%

Next Steps

Further Reading


Key Takeaway: ClaudeKit enables systematic performance optimization with profiling, analysis, and implementation of best practices - turning slow applications into fast ones in under an hour with measurable improvements.