Performance Optimization Deep Dive for Claude Code

This comprehensive guide consolidates all aspects of performance optimization for Claude Code, covering everything from managing Claude’s own resources to optimizing the applications you build. Whether you’re looking to reduce costs, improve response times, or scale your AI-powered development, this guide provides the complete picture.

📋 Table of Contents

Claude Code Performance

  1. Context Window Management
  2. Memory Usage Optimization
  3. Token Usage Analytics
  4. Tool Call Optimization
  5. Response Time Improvements
  6. Cost Optimization Strategies

Application Performance

  1. Memory Profiling and Optimization
  2. Database Query Optimization
  3. Frontend Bundle Size Reduction
  4. API Response Time Improvements
  5. Caching Strategies Implementation
  6. Real-Time Performance Monitoring

Advanced Topics

  1. Multi-Agent Cost Optimization
  2. Prompt Caching Patterns
  3. Cache Invalidation Strategies
  4. Performance Testing and Benchmarking

LLM/AI Application Optimization

  1. LLM Performance Optimization Guide - Comprehensive 2024 techniques for token usage, latency reduction, cost optimization, caching strategies, and real-world benchmarks

🎯 Quick Start Performance Checklist

Before diving into the details, here’s what you need to know:

Immediate Actions (First Day)

  • Enable /compact command usage at 60% context
  • Set up basic token tracking
  • Configure CLAUDE.md for persistent context
  • Enable prompt caching for system prompts

Quick Wins (First Week)

  • Implement parallel tool execution patterns
  • Set up cost alerts and monitoring
  • Deploy simple caching strategies
  • Create context management workflows

Long-term Optimization (First Month)

  • Build comprehensive monitoring dashboard
  • Implement multi-agent orchestration
  • Deploy intelligent cache invalidation
  • Create performance regression detection

Claude Code Performance Optimization

Context Window Management

Claude Code’s context window is your most precious resource. Understanding and managing it effectively is crucial for productive development sessions.

Understanding Context Windows

Your context window includes:

  • Current conversation history
  • File contents you’ve read
  • Tool outputs and results
  • System prompts and instructions
  • CLAUDE.md file contents

The Power of /compact

The /compact command is your primary tool for context management:

# Use /compact when:
- Context usage exceeds 60%
- Before starting new complex tasks
- After completing major milestones
- When switching between different parts of a project
 
# What it does:
- Preserves critical information
- Removes redundancy
- Maintains conversation continuity
- Reduces token usage and costs

Real-Time Context Monitoring

Monitor your context usage through the UI indicator:

Context: 42% [========    ]      # Healthy
Context: 75% [==============  ]   # Time to consider compaction
Context: 90% [=================] ⚠️ # Critical - compact now

Context Management Strategies

1. Proactive Compaction Pattern

class ContextManager:
    def __init__(self, threshold=60):
        self.threshold = threshold
        self.checkpoints = []
    
    def should_compact(self, usage):
        return usage > self.threshold
    
    def create_checkpoint(self, description):
        """Save progress before compaction"""
        checkpoint = {
            'timestamp': datetime.now(),
            'description': description,
            'context_usage': self.get_current_usage()
        }
        self.checkpoints.append(checkpoint)
        return checkpoint

2. Selective File Reading

Instead of reading entire large files:

// BAD: Reading everything
const entireFile = await readFile('large-config.json');
 
// GOOD: Read only what you need
const config = await readFile('large-config.json', {
  offset: 1000,  // Start at line 1000
  limit: 100     // Read only 100 lines
});

3. Structured Information Retention

Optimize your CLAUDE.md structure:

# Project CLAUDE.md
 
## Architecture Overview (Keep Concise)
- Microservices: Auth, API, Database
- Stack: Node.js 20, PostgreSQL 15, Redis
- Deployment: Kubernetes on AWS
 
## Coding Standards (Essential Only)
- TypeScript strict mode
- 2-space indentation
- Jest for testing
 
## Current Context (Update Frequently)
- Working on: OAuth integration
- Key decisions: Using passport.js
- Next steps: Implement refresh tokens
 
## Performance Notes
- Large files: data/*.json (use pagination)
- Slow operations: Database migrations
- Memory intensive: Image processing

Advanced Context Optimization for Large Codebases

Chunked Analysis Pattern

Break large codebases into manageable pieces:

class CodebaseChunker:
    def __init__(self, root_path, chunk_size=50):
        self.root_path = Path(root_path)
        self.chunk_size = chunk_size
    
    def create_analysis_chunks(self):
        """Create logical chunks for analysis"""
        chunks = {
            'core': self.find_files('src/core'),
            'features': self.find_files('src/features'),
            'tests': self.find_files('tests'),
        }
        
        for category, files in chunks.items():
            file_groups = [files[i:i+self.chunk_size] 
                          for i in range(0, len(files), self.chunk_size)]
            
            for idx, group in enumerate(file_groups):
                yield f"Analyze {category} chunk {idx+1}: {group}"

Summary Chain Pattern

Build understanding incrementally:

# Step 1: High-level architecture
"Analyze the overall architecture in src/"
 
# Step 2: Core modules
"Based on the architecture, explain the core modules"
 
# Step 3: Feature integration
"Explain how features interact with core"
 
# Step 4: Specific implementation
"Now help implement a new payment feature"

Memory Usage Optimization

Environment Configuration

Configure Claude Code for optimal memory usage:

# Set Node.js memory limit
export NODE_OPTIONS="--max-old-space-size=4096"
 
# Configure timeouts
export BASH_DEFAULT_TIMEOUT_MS=120000  # 2 minutes
export BASH_MAX_TIMEOUT_MS=600000      # 10 minutes
 
# Maintain working directory
export CLAUDE_BASH_MAINTAIN_PROJECT_WORKING_DIR=true

Shell Snapshot Management

Claude Code uses in-memory shell snapshots:

# Monitor snapshot size
du -sh ~/.claude
 
# Clean old snapshots
find ~/.claude -type f -mtime +7 -delete
 
# Automated cleanup script
#!/bin/bash
CLAUDE_DIR="$HOME/.claude"
MAX_SIZE_MB=500
 
current_size=$(du -sm "$CLAUDE_DIR" | cut -f1)
if [ $current_size -gt $MAX_SIZE_MB ]; then
    find "$CLAUDE_DIR" -type f -mtime +3 -delete
    echo "Cleaned old Claude snapshots"
fi

Auto-Compaction Settings

Claude Code auto-compacts at 80% context usage. Work with this:

// Pattern: Break complex tasks into stages
async function complexWorkflow() {
  // Stage 1: Analysis
  await analyzeCodebase();
  console.log("💡 Use /compact to free context");
  
  // Stage 2: Implementation
  await implementChanges();
  console.log("💡 Use /compact before testing");
  
  // Stage 3: Testing
  await runTests();
}

Token Usage Analytics

Effective token monitoring is crucial for cost management and optimization.

Token Economics (2025 Pricing)

const TOKEN_COSTS = {
  "claude-4-opus": {
    input: 15.00,      // per million tokens
    output: 75.00,     
    cacheWrite: 18.75, // 25% premium
    cacheRead: 1.50    // 90% discount
  },
  "claude-4-sonnet": {
    input: 3.00,
    output: 15.00,
    cacheWrite: 3.75,
    cacheRead: 0.30
  },
  "claude-3-5-haiku": {
    input: 0.80,
    output: 4.00,
    cacheWrite: 1.00,
    cacheRead: 0.08
  }
};

Comprehensive Token Tracking System

@dataclass
class TokenUsage:
    timestamp: str
    model: str
    request_id: str
    input_tokens: int
    output_tokens: int
    cache_creation_tokens: int
    cache_read_tokens: int
    total_cost: float
    latency_ms: int
    user_id: Optional[str] = None
    session_id: Optional[str] = None
    prompt_category: Optional[str] = None
 
class TokenAnalytics:
    def __init__(self, db_path: str = "token_usage.db"):
        self.db_path = db_path
        self._init_db()
    
    def track_usage(self, response, latency_ms, **metadata):
        """Track token usage from API response"""
        usage = response.usage
        model = response.model
        
        # Calculate costs
        model_costs = self._get_model_costs(model)
        total_cost = self._calculate_total_cost(usage, model_costs)
        
        # Create and save usage record
        usage_record = TokenUsage(
            timestamp=datetime.utcnow().isoformat(),
            model=model,
            request_id=response.id,
            input_tokens=usage.input_tokens,
            output_tokens=usage.output_tokens,
            cache_creation_tokens=getattr(usage, 'cache_creation_input_tokens', 0),
            cache_read_tokens=getattr(usage, 'cache_read_input_tokens', 0),
            total_cost=total_cost,
            latency_ms=latency_ms,
            **metadata
        )
        
        self._save_usage(usage_record)
        return usage_record

Real-Time Monitoring Dashboard

class TokenMonitor extends EventEmitter {
  private metrics: TokenMetrics[] = [];
  private alerts: Map<string, AlertRule> = new Map();
  
  recordMetrics(metrics: TokenMetrics) {
    this.metrics.push(metrics);
    this.emit('metrics', metrics);
    this.checkAlerts();
  }
  
  addAlert(rule: AlertRule) {
    // Example: Cost alert
    this.alerts.set('high-cost', {
      type: 'cost',
      threshold: 10.00, // $10 in 5 minutes
      window: 300,
      action: (metrics) => {
        console.error(`⚠️ High cost alert: $${
          metrics.reduce((sum, m) => sum + m.cost, 0).toFixed(2)
        } in last 5 minutes`);
      }
    });
  }
}

Token Usage Optimization Patterns

def optimize_prompt(prompt: str, max_tokens: int = 1000) -> str:
    """Optimize prompt to reduce token usage"""
    
    # Remove excessive whitespace
    prompt = ' '.join(prompt.split())
    
    # Use abbreviations
    replacements = {
        "artificial intelligence": "AI",
        "machine learning": "ML",
        "for example": "e.g.",
    }
    
    for full, abbr in replacements.items():
        prompt = prompt.replace(full, abbr)
    
    # Truncate if needed
    if len(prompt) > max_tokens * 4:
        prompt = prompt[:max_tokens * 4] + "..."
    
    return prompt

Tool Call Optimization

Maximize performance through intelligent tool usage.

Parallel Tool Execution

// INEFFICIENT: Sequential calls
const status = await bash('git status');
const diff = await bash('git diff');
const log = await bash('git log -5');
 
// EFFICIENT: Parallel execution
const [status, diff, log] = await Promise.all([
  bash('git status'),
  bash('git diff'),
  bash('git log -5')
]);

Batched Operations

// INEFFICIENT: Multiple individual edits
await edit('file.ts', 'old1', 'new1');
await edit('file.ts', 'old2', 'new2');
await edit('file.ts', 'old3', 'new3');
 
// EFFICIENT: Single multi-edit
await multiEdit('file.ts', [
  { old: 'old1', new: 'new1' },
  { old: 'old2', new: 'new2' },
  { old: 'old3', new: 'new3' }
]);

Search Tool Selection

Choose the right tool for each task:

// For specific file patterns
const files = await glob('**/*.test.ts');
 
// For content search in known files
const results = await grep('TODO', { glob: '*.ts' });
 
// For complex, multi-step searches
const findings = await task({
  description: "Find all API endpoints",
  prompt: "Search for REST API endpoint definitions"
});

Tool Optimization Pattern

class ToolOptimizer {
  async optimizeToolCalls(plannedCalls: ToolCall[]): Promise<OptimizedToolCalls> {
    // Batch similar operations
    const batched = this.batchOperations(plannedCalls);
    
    // Parallelize independent calls
    const parallelized = this.parallelizeIndependent(batched);
    
    // Cache frequent results
    const cached = await this.applyCaching(parallelized);
    
    // Reorder for efficiency
    const reordered = this.reorderForEfficiency(cached);
    
    return {
      calls: reordered,
      estimatedSavings: this.calculateSavings(plannedCalls, reordered)
    };
  }
}

Response Time Improvements

Thinking Mode Optimization

Use appropriate thinking levels:

Task TypeThinking ModeUse Case
SimpleNo keywordFile reads, basic edits
ModeratethinkDesign decisions, algorithm choices
Complexthink hardArchitecture design, optimization
Very Complexthink harderMulti-system integration
ExtremeultrathinkNovel algorithms, critical decisions

Prompt Optimization for Speed

## INEFFICIENT Prompt
"Can you help me understand the codebase and then maybe implement 
a new feature for user authentication with JWT tokens and also 
make sure it's secure and follows best practices?"
 
## EFFICIENT Prompt
"Implement JWT authentication:
1. Add JWT middleware to Express
2. Create /auth/login endpoint
3. Secure existing /api routes
Use bcrypt for passwords, 1h token expiry"

Selective Context Loading

// INEFFICIENT: Loading entire modules
import * as utils from './utils';
 
// EFFICIENT: Specific imports
import { validateEmail, hashPassword } from './utils';

Cost Optimization Strategies

Token-Efficient Patterns

// 1. Use concise variable names in examples
// BAD: 
const userAuthenticationTokenWithRefreshCapability = generateToken();
 
// GOOD:
const authToken = generateToken();
 
// 2. Avoid redundant file reads
// BAD:
const file1 = await read('config.json');
// ... later ...
const file2 = await read('config.json'); // Redundant
 
// GOOD:
const config = await read('config.json');
// Reuse config variable
 
// 3. Summarize large outputs
const summary = await task({
  prompt: "Summarize key errors from this log",
  content: largeLogFile
});

Context Budget Management

class ContextBudget {
  private budget = 100; // Percentage
  
  allocate(task: string): number {
    const allocations = {
      'file-reading': 10,
      'code-generation': 20,
      'debugging': 30,
      'refactoring': 25,
      'documentation': 15
    };
    
    return allocations[task] || 20;
  }
  
  shouldCompact(): boolean {
    return this.budget < 20;
  }
}

Cost Analysis and ROI

def calculate_roi(
    requests_per_day: int,
    avg_input_tokens: int,
    cache_hit_rate: float = 0.8,
    days: int = 30
) -> Dict[str, float]:
    """Calculate ROI for implementing optimizations"""
    
    STANDARD_COST = 3.00  # per MTok
    CACHE_READ_COST = 0.30  # per MTok
    
    total_requests = requests_per_day * days
    tokens_per_request = avg_input_tokens / 1_000_000
    
    # Without optimization
    cost_without = total_requests * tokens_per_request * STANDARD_COST
    
    # With optimization
    cache_reads = total_requests * cache_hit_rate
    uncached = total_requests * (1 - cache_hit_rate)
    
    cost_with = (
        (cache_reads * tokens_per_request * CACHE_READ_COST) +
        (uncached * tokens_per_request * STANDARD_COST)
    )
    
    savings = cost_without - cost_with
    roi_percentage = (savings / cost_without) * 100
    
    return {
        "monthly_savings": savings,
        "roi_percentage": roi_percentage,
        "cost_reduction": f"{roi_percentage:.1f}%"
    }

Application Performance Optimization

Memory Profiling and Optimization

Memory Baseline and Monitoring

// Step 1: Capture baseline memory usage
console.log('Initial memory:', process.memoryUsage());
 
// Step 2: Set up periodic monitoring
setInterval(() => {
  const usage = process.memoryUsage();
  console.log(`Memory: RSS ${usage.rss / 1024 / 1024} MB, Heap ${usage.heapUsed / 1024 / 1024} MB`);
}, 5000);
 
// Step 3: Connect Chrome DevTools
// Start with: node --inspect server.js
// Open chrome://inspect and take heap snapshots

Common Memory Leak Patterns

// 1. Event Listener Leaks
// BAD:
emitter.on('data', handler);
 
// GOOD:
emitter.on('data', handler);
// Later...
emitter.removeListener('data', handler);
 
// 2. Closure Memory Leaks
// BAD:
function createLeak() {
  const largeData = new Array(1000000);
  return function() {
    console.log(largeData.length); // Keeps largeData in memory
  };
}
 
// GOOD:
function avoidLeak() {
  const dataLength = new Array(1000000).length;
  return function() {
    console.log(dataLength); // Only keeps the number
  };
}
 
// 3. Unbounded Caches
// BAD:
const cache = {};
function addToCache(key, value) {
  cache[key] = value; // Grows forever
}
 
// GOOD:
const LRU = require('lru-cache');
const cache = new LRU({ max: 500 });

Memory Optimization Techniques

// 1. Object Pooling
class ObjectPool {
  constructor(createFn, resetFn, maxSize = 100) {
    this.createFn = createFn;
    this.resetFn = resetFn;
    this.pool = [];
    this.maxSize = maxSize;
  }
  
  acquire() {
    return this.pool.pop() || this.createFn();
  }
  
  release(obj) {
    if (this.pool.length < this.maxSize) {
      this.resetFn(obj);
      this.pool.push(obj);
    }
  }
}
 
// 2. Stream Processing for Large Data
const fs = require('fs');
const stream = require('stream');
 
// Process large files without loading into memory
fs.createReadStream('huge-file.json')
  .pipe(new stream.Transform({
    transform(chunk, encoding, callback) {
      // Process chunk by chunk
      const processed = processChunk(chunk);
      callback(null, processed);
    }
  }))
  .pipe(fs.createWriteStream('output.json'));

Database Query Optimization

PostgreSQL Optimization

-- 1. Analyze current performance
\timing on
 
SELECT query, calls, mean_time, total_time
FROM pg_stat_statements
ORDER BY mean_time DESC
LIMIT 10;
 
-- 2. Use EXPLAIN ANALYZE
EXPLAIN (ANALYZE, BUFFERS) 
SELECT * FROM orders 
WHERE customer_id = 123 
AND created_at > '2025-01-01';
 
-- 3. Index optimization
-- Check for missing indexes
SELECT schemaname, tablename, attname, n_distinct, correlation
FROM pg_stats
WHERE schemaname NOT IN ('pg_catalog', 'information_schema')
AND n_distinct > 100
AND correlation < 0.1
ORDER BY n_distinct DESC;
 
-- Create appropriate indexes
CREATE INDEX CONCURRENTLY idx_orders_customer_created 
ON orders(customer_id, created_at);
 
-- 4. Update statistics and maintenance
ANALYZE orders;
VACUUM ANALYZE orders;

MySQL Optimization

-- 1. Enable slow query log
SET GLOBAL slow_query_log = 'ON';
SET GLOBAL long_query_time = 2;
 
-- 2. Analyze query performance
EXPLAIN FORMAT=JSON
SELECT * FROM products p
JOIN categories c ON p.category_id = c.id
WHERE p.price > 100;
 
-- 3. Optimize based on workload
-- OLTP: Smaller buffer pool, optimize for writes
SET GLOBAL innodb_buffer_pool_size = 1G;
SET GLOBAL innodb_flush_log_at_trx_commit = 2;
 
-- OLAP: Larger buffer pool, optimize for reads
SET GLOBAL innodb_buffer_pool_size = 8G;
SET GLOBAL innodb_read_ahead_threshold = 0;

Query Optimization Patterns

// 1. Batch Operations
// BAD: N+1 queries
const users = await db.query('SELECT * FROM users');
for (const user of users) {
  user.orders = await db.query('SELECT * FROM orders WHERE user_id = ?', [user.id]);
}
 
// GOOD: Join or batch fetch
const users = await db.query(`
  SELECT u.*, o.* 
  FROM users u 
  LEFT JOIN orders o ON u.id = o.user_id
`);
 
// 2. Pagination
// BAD: Offset pagination
SELECT * FROM products LIMIT 1000 OFFSET 10000; // Slow on large offsets
 
// GOOD: Cursor pagination
SELECT * FROM products 
WHERE id > ? 
ORDER BY id 
LIMIT 1000;
 
// 3. Materialized Views for Complex Aggregations
CREATE MATERIALIZED VIEW sales_summary AS
SELECT 
  DATE_TRUNC('day', created_at) as date,
  product_category,
  SUM(amount) as total_sales,
  COUNT(*) as order_count
FROM orders
GROUP BY 1, 2;
 
CREATE INDEX ON sales_summary(date, product_category);

Frontend Bundle Size Reduction

Modern Build Tool Optimization

// vite.config.js - Optimal configuration
export default {
  build: {
    // Enable tree shaking
    rollupOptions: {
      treeshake: {
        moduleSideEffects: false,
        propertyReadSideEffects: false,
        tryCatchDeoptimization: false
      },
      // Manual chunks for better caching
      output: {
        manualChunks: {
          vendor: ['react', 'react-dom'],
          ui: ['@mui/material'],
          utils: ['lodash-es', 'date-fns']
        }
      }
    },
    // Optimize chunk size
    chunkSizeWarningLimit: 500,
    // Enable minification
    minify: 'terser',
    terserOptions: {
      compress: {
        drop_console: true,
        drop_debugger: true
      }
    }
  }
}

Code Splitting Strategies

// 1. Route-based splitting
import { lazy, Suspense } from 'react';
 
const Dashboard = lazy(() => import('./Dashboard'));
const Analytics = lazy(() => import('./Analytics'));
 
function App() {
  return (
    <Suspense fallback={<Loading />}>
      <Routes>
        <Route path="/dashboard" element={<Dashboard />} />
        <Route path="/analytics" element={<Analytics />} />
      </Routes>
    </Suspense>
  );
}
 
// 2. Component-based splitting
const HeavyChart = lazy(() => 
  import(/* webpackChunkName: "charts" */ './HeavyChart')
);
 
// 3. Conditional loading
const loadPdfLibrary = async () => {
  const { PDFDocument } = await import('pdf-lib');
  return PDFDocument;
};

Dependency Optimization

// 1. Replace heavy libraries
// Before: lodash (70KB)
import { debounce } from 'lodash';
 
// After: lodash-es with tree shaking (4KB)
import debounce from 'lodash-es/debounce';
 
// Or use native alternatives
const debounce = (fn, delay) => {
  let timeoutId;
  return (...args) => {
    clearTimeout(timeoutId);
    timeoutId = setTimeout(() => fn(...args), delay);
  };
};
 
// 2. Dynamic imports for optional features
button.addEventListener('click', async () => {
  const { exportToPDF } = await import('./pdf-export');
  exportToPDF(data);
});

Bundle Analysis and Monitoring

// package.json - Add size monitoring
{
  "scripts": {
    "build": "vite build",
    "analyze": "vite build --report",
    "size-limit": "size-limit"
  },
  "size-limit": [
    {
      "path": "dist/assets/index-*.js",
      "limit": "150 KB"
    },
    {
      "path": "dist/assets/vendor-*.js",
      "limit": "200 KB"
    }
  ]
}

API Response Time Improvements

Request-Level Monitoring

// Express middleware for comprehensive timing
const performanceMiddleware = (req, res, next) => {
  const start = process.hrtime.bigint();
  
  // Track database queries
  req.dbQueries = [];
  const originalQuery = db.query;
  db.query = async (...args) => {
    const queryStart = process.hrtime.bigint();
    const result = await originalQuery.apply(db, args);
    const queryTime = Number(process.hrtime.bigint() - queryStart) / 1000000;
    req.dbQueries.push({ query: args[0], time: queryTime });
    return result;
  };
  
  res.on('finish', () => {
    const duration = Number(process.hrtime.bigint() - start) / 1000000;
    const dbTime = req.dbQueries.reduce((sum, q) => sum + q.time, 0);
    
    console.log({
      method: req.method,
      path: req.path,
      totalTime: `${duration}ms`,
      dbTime: `${dbTime}ms`,
      dbQueries: req.dbQueries.length,
      statusCode: res.statusCode
    });
  });
  
  next();
};

Caching Layer Implementation

// Multi-level caching system
const NodeCache = require('node-cache');
const Redis = require('ioredis');
 
class MultiLevelCache {
  constructor() {
    this.l1Cache = new NodeCache({ stdTTL: 60 }); // Memory cache
    this.l2Cache = new Redis(); // Redis cache
  }
  
  async get(key) {
    // Check L1 (memory)
    let value = this.l1Cache.get(key);
    if (value) return { value, source: 'memory' };
    
    // Check L2 (Redis)
    value = await this.l2Cache.get(key);
    if (value) {
      value = JSON.parse(value);
      this.l1Cache.set(key, value); // Promote to L1
      return { value, source: 'redis' };
    }
    
    return { value: null, source: null };
  }
  
  async set(key, value, ttl = 3600) {
    // Set in both caches
    this.l1Cache.set(key, value, Math.min(ttl, 300));
    await this.l2Cache.setex(key, ttl, JSON.stringify(value));
  }
  
  // Implement cache-aside pattern
  async getOrSet(key, fetchFn, ttl = 3600) {
    const cached = await this.get(key);
    if (cached.value) return cached.value;
    
    const value = await fetchFn();
    await this.set(key, value, ttl);
    return value;
  }
}
 
// Usage
const cache = new MultiLevelCache();
 
app.get('/api/products/:id', async (req, res) => {
  const product = await cache.getOrSet(
    `product:${req.params.id}`,
    () => db.query('SELECT * FROM products WHERE id = ?', [req.params.id]),
    3600 // 1 hour cache
  );
  
  res.json(product);
});

Response Optimization

// 1. Enable compression
const compression = require('compression');
app.use(compression({
  filter: (req, res) => {
    if (req.headers['x-no-compression']) return false;
    return compression.filter(req, res);
  },
  level: 6 // Balance between speed and compression ratio
}));
 
// 2. Implement field filtering
app.get('/api/users', (req, res) => {
  const fields = req.query.fields?.split(',') || [];
  const users = await db.query('SELECT * FROM users');
  
  if (fields.length > 0) {
    const filtered = users.map(user => 
      fields.reduce((obj, field) => {
        if (user[field] !== undefined) obj[field] = user[field];
        return obj;
      }, {})
    );
    res.json(filtered);
  } else {
    res.json(users);
  }
});
 
// 3. Implement streaming for large responses
app.get('/api/export/users', async (req, res) => {
  res.setHeader('Content-Type', 'application/json');
  res.write('['); // Start JSON array
  
  let first = true;
  const stream = db.stream('SELECT * FROM users');
  
  stream.on('data', (user) => {
    if (!first) res.write(',');
    res.write(JSON.stringify(user));
    first = false;
  });
  
  stream.on('end', () => {
    res.write(']'); // Close JSON array
    res.end();
  });
});

Caching Strategies Implementation

Redis Caching Patterns

class CacheManager {
  constructor(redis, defaultTTL = 3600) {
    this.redis = redis;
    this.defaultTTL = defaultTTL;
  }
  
  // 1. Cache-Aside Pattern
  async getOrSet(key, fetchFn, ttl = this.defaultTTL) {
    let value = await this.get(key);
    
    if (value === null) {
      value = await fetchFn();
      await this.set(key, value, ttl);
    }
    
    return value;
  }
  
  // 2. Write-Through Pattern
  async writeThrough(key, value, writeFn, ttl = this.defaultTTL) {
    await writeFn(value); // Write to database first
    await this.set(key, value, ttl); // Then update cache
    return value;
  }
  
  // 3. Write-Behind Pattern (risky but fast)
  async writeBehind(key, value, writeFn, ttl = this.defaultTTL) {
    await this.set(key, value, ttl); // Update cache immediately
    
    // Queue database write
    setImmediate(async () => {
      try {
        await writeFn(value);
      } catch (error) {
        console.error('Write-behind failed:', error);
        await this.invalidate(key); // Invalidate on failure
      }
    });
    
    return value;
  }
  
  // 4. Cache Invalidation
  async invalidate(pattern) {
    const keys = await this.redis.keys(pattern);
    if (keys.length > 0) {
      await this.redis.del(...keys);
    }
    return keys.length;
  }
}

Tag-Based Cache Invalidation

class TaggedCache extends CacheManager {
  async setWithTags(key, value, tags, ttl = this.defaultTTL) {
    await this.set(key, value, ttl);
    
    // Store reverse mapping
    for (const tag of tags) {
      await this.redis.sadd(`tag:${tag}`, key);
      await this.redis.expire(`tag:${tag}`, ttl);
    }
  }
  
  async invalidateByTag(tag) {
    const keys = await this.redis.smembers(`tag:${tag}`);
    if (keys.length > 0) {
      await this.redis.del(...keys);
      await this.redis.del(`tag:${tag}`);
    }
    return keys.length;
  }
}
 
// Usage
const cache = new TaggedCache(redis);
 
// Cache with tags
await cache.setWithTags(
  'user:123:profile',
  userData,
  ['user:123', 'profiles'],
  3600
);
 
// Invalidate all user:123 related cache
await cache.invalidateByTag('user:123');

Cache Warming Strategy

class CacheWarmer {
  constructor(cache) {
    this.cache = cache;
    this.warmingTasks = new Map();
  }
  
  register(name, fetchFn, keys, schedule = '0 */6 * * *') {
    this.warmingTasks.set(name, { fetchFn, keys, schedule });
  }
  
  async warmCache(name) {
    const task = this.warmingTasks.get(name);
    if (!task) return;
    
    console.log(`Warming cache for ${name}`);
    const results = await Promise.allSettled(
      task.keys.map(key => 
        task.fetchFn(key)
          .then(value => this.cache.set(key, value))
          .catch(err => console.error(`Failed to warm ${key}:`, err))
      )
    );
    
    const success = results.filter(r => r.status === 'fulfilled').length;
    console.log(`Cache warming complete: ${success}/${task.keys.length} successful`);
  }
  
  startScheduled() {
    const cron = require('node-cron');
    
    for (const [name, task] of this.warmingTasks) {
      cron.schedule(task.schedule, () => this.warmCache(name));
    }
  }
}
 
// Usage
const warmer = new CacheWarmer(cache);
 
warmer.register(
  'popular-products',
  async (id) => await db.getProduct(id),
  ['prod:1', 'prod:2', 'prod:3'], // Most popular product IDs
  '0 */4 * * *' // Every 4 hours
);
 
warmer.startScheduled();

Real-Time Performance Monitoring

Distributed Tracing Implementation

class TraceContext {
  private spans: Map<string, Span> = new Map();
  
  startSpan(name: string, parent?: string): Span {
    const span = {
      id: generateSpanId(),
      traceId: this.traceId,
      name,
      startTime: performance.now(),
      parent,
      tags: new Map<string, any>(),
      events: []
    };
    
    this.spans.set(span.id, span);
    return span;
  }
  
  async instrumentOperation<T>(
    name: string,
    operation: () => Promise<T>
  ): Promise<T> {
    const span = this.startSpan(name);
    
    try {
      const result = await operation();
      span.tags.set('status', 'success');
      return result;
    } catch (error) {
      span.tags.set('status', 'error');
      span.tags.set('error', error.message);
      throw error;
    } finally {
      this.endSpan(span.id);
    }
  }
}
 
// Usage with Express
app.use((req, res, next) => {
  req.trace = new TraceContext();
  req.trace.instrumentOperation('http.request', () => next());
});

Performance Anomaly Detection

class PerformanceAnalytics {
  private windows: Map<string, TimeWindow> = new Map();
  
  detectAnomalies(metric: MetricEvent): Anomaly[] {
    const anomalies = [];
    
    // Response time anomaly
    if (metric.type === 'response_time') {
      const baseline = this.getBaseline('response_time');
      if (metric.value > baseline * 2) {
        anomalies.push({
          type: 'performance_degradation',
          severity: 'high',
          metric: 'response_time',
          value: metric.value,
          threshold: baseline * 2
        });
      }
    }
    
    // Implement automatic remediation
    if (anomalies.length > 0) {
      this.autoRemediate(anomalies);
    }
    
    return anomalies;
  }
  
  private async autoRemediate(anomalies: Anomaly[]) {
    for (const anomaly of anomalies) {
      switch (anomaly.type) {
        case 'performance_degradation':
          await this.scaleResources();
          break;
        case 'memory_leak':
          await this.triggerGarbageCollection();
          break;
        case 'high_error_rate':
          await this.enableCircuitBreaker();
          break;
      }
    }
  }
}

Real-Time Dashboard Configuration

const dashboardConfig = {
  widgets: {
    TaskThroughput: {
      type: 'timeseries',
      metrics: ['tasks.completed', 'tasks.failed'],
      window: '1h',
      refreshRate: 5000,
      alerts: {
        low_throughput: {
          condition: 'value < 10',
          severity: 'warning'
        }
      }
    },
    
    ResponseTimeHeatmap: {
      type: 'heatmap',
      metric: 'response_time',
      percentiles: [50, 75, 90, 95, 99],
      colorScale: {
        good: { max: 100 },
        warning: { max: 500 },
        critical: { max: 1000 }
      }
    },
    
    ErrorRate: {
      type: 'gauge',
      metric: 'error_rate',
      calculation: 'errors / total_requests * 100',
      thresholds: {
        green: { max: 1 },
        yellow: { max: 5 },
        red: { max: 10 }
      }
    }
  }
};

Advanced Performance Topics

Multi-Agent Cost Optimization

Managing multiple Claude agents requires sophisticated orchestration to control costs while maintaining performance.

Shared Context Management

@dataclass
class SharedContext:
    id: str
    content: str
    content_hash: str
    created_at: datetime
    agents_using: Set[str]
    cache_tokens: int = 0
 
class MultiAgentContextManager:
    def __init__(self, anthropic_client):
        self.client = anthropic_client
        self.shared_contexts: Dict[str, SharedContext] = {}
        self.agent_contexts: Dict[str, List[str]] = {}
    
    async def register_shared_context(self, content: str, context_type: str = "general") -> str:
        """Register content that will be shared across agents."""
        content_hash = hashlib.sha256(content.encode()).hexdigest()
        
        # Check if this content already exists
        for ctx_id, ctx in self.shared_contexts.items():
            if ctx.content_hash == content_hash:
                return ctx_id
        
        # Create new shared context
        context_id = f"{context_type}_{content_hash[:8]}"
        shared_context = SharedContext(
            id=context_id,
            content=content,
            content_hash=content_hash,
            created_at=datetime.utcnow(),
            agents_using=set(),
            cache_tokens=len(content) // 4
        )
        
        self.shared_contexts[context_id] = shared_context
        return context_id
    
    def get_cost_analysis(self) -> Dict[str, any]:
        """Analyze cost savings from context sharing."""
        total_cached_tokens = sum(
            ctx.cache_tokens * len(ctx.agents_using) 
            for ctx in self.shared_contexts.values()
        )
        
        # Cost calculations
        standard_cost = (total_cached_tokens / 1_000_000) * 3.00
        cached_cost = (total_cached_tokens / 1_000_000) * 0.30
        savings = standard_cost - cached_cost
        
        return {
            "total_shared_contexts": len(self.shared_contexts),
            "estimated_savings": f"${savings:.2f}",
            "cost_reduction_percent": ((savings / standard_cost) * 100) if standard_cost > 0 else 0
        }

Agent Request Orchestration

class MultiAgentOrchestrator extends EventEmitter {
  private requestQueue: PQueue;
  private agentQuotas: Map<string, AgentQuota> = new Map();
  
  constructor(concurrency: number = 5) {
    super();
    this.requestQueue = new PQueue({ 
      concurrency,
      interval: 1000,
      intervalCap: 10 // Max 10 requests per second
    });
  }
  
  async submitRequest(request: AgentRequest): Promise<string> {
    // Validate agent quota
    const quota = this.agentQuotas.get(request.agentId);
    if (!this.canExecuteRequest(request, quota)) {
      // Defer request until quota refreshes
      setTimeout(() => this.submitRequest(request), quota.resetTime - Date.now());
      return request.id;
    }
    
    // Queue for execution with priority
    this.requestQueue.add(
      () => this.executeRequest(request),
      { priority: request.priority }
    );
    
    return request.id;
  }
}

Dynamic Model Selection

class DynamicModelSelector:
    def __init__(self):
        self.models = {
            "claude-3-5-haiku": ModelCapability(
                "claude-3-5-haiku", 0.80, 0.7, 0.9, 200000
            ),
            "claude-3-5-sonnet": ModelCapability(
                "claude-3-5-sonnet", 3.00, 0.85, 0.7, 200000
            ),
            "claude-4-opus": ModelCapability(
                "claude-4-opus", 15.00, 0.95, 0.5, 200000
            )
        }
    
    def select_model(self, task_description: str, context_length: int, 
                     budget_constraint: Optional[float] = None) -> Tuple[str, Dict]:
        """Select optimal model based on task requirements."""
        complexity = self._detect_complexity(task_description)
        
        # Filter eligible models
        eligible_models = []
        for name, model in self.models.items():
            if (model.quality_score >= complexity.min_quality and 
                model.cost_per_mtok <= (budget_constraint or float('inf'))):
                eligible_models.append((name, model))
        
        # Score and rank
        best_model = max(eligible_models, 
                        key=lambda x: self._calculate_score(x[1], complexity))
        
        return best_model[0], {
            "complexity": complexity.value,
            "estimated_cost": (context_length / 1_000_000) * best_model[1].cost_per_mtok
        }

Prompt Caching Patterns

Prompt caching can reduce costs by up to 90% for repeated operations.

Basic Caching Implementation

class CachedClaudeClient:
    def __init__(self, api_key: str):
        self.client = anthropic.Anthropic(api_key=api_key)
        self.cache_metrics = {
            "cache_writes": 0,
            "cache_reads": 0,
            "total_saved": 0.0
        }
    
    def create_cached_message(self, system_prompt: str, context: str, 
                            user_query: str, model: str = "claude-3-5-sonnet-20241022"):
        """Create a message with intelligent caching."""
        messages = [{
            "role": "user",
            "content": [
                {
                    "type": "text",
                    "text": system_prompt,
                    "cache_control": {"type": "ephemeral"}  # Cache system instructions
                },
                {
                    "type": "text", 
                    "text": context,
                    "cache_control": {"type": "ephemeral"}  # Cache large context
                },
                {
                    "type": "text",
                    "text": user_query  # Don't cache variable user input
                }
            ]
        }]
        
        response = self.client.messages.create(
            model=model,
            messages=messages,
            max_tokens=1000
        )
        
        self._update_metrics(response)
        return response

Multi-Agent Caching

class MultiAgentCacheManager:
    def __init__(self, client: anthropic.Anthropic):
        self.client = client
        self.context_cache = {}
        self.cache_usage = {}
    
    def create_agent_message(self, agent_id: str, query: str):
        """Create message with cached agent context."""
        context = self.context_cache[agent_id]
        
        messages = [{
            "role": "user",
            "content": [
                {
                    "type": "text",
                    "text": context.system_instructions,
                    "cache_control": {"type": "ephemeral"}
                },
                {
                    "type": "text",
                    "text": context.shared_knowledge,
                    "cache_control": {"type": "ephemeral"}
                },
                {
                    "type": "text",
                    "text": query
                }
            ]
        }]
        
        response = self.client.messages.create(
            model="claude-3-5-sonnet-20241022",
            messages=messages,
            max_tokens=2000
        )
        
        self._track_usage(agent_id, response)
        return response

Cache Warming Strategy

async def warm_cache(client: CachedClaudeClient, contexts: List[Dict[str, str]]):
    """Pre-warm cache with common contexts."""
    for context in contexts:
        try:
            await client.create_cached_message(
                system_prompt=context["system"],
                context=context["data"],
                user_query="Cache warming - please acknowledge.",
                model="claude-3-5-haiku-20241022"  # Use cheaper model
            )
            print(f"✓ Warmed cache for: {context['name']}")
        except Exception as e:
            print(f"✗ Failed to warm cache for {context['name']}: {e}")

Cache Invalidation Strategies

Time-Based Invalidation (TTL)

class TTLCache:
    def __init__(self):
        self.cache: Dict[str, Dict[str, Any]] = {}
        self.default_ttl = 300  # 5 minutes
    
    def set(self, key: str, value: Any, ttl: Optional[int] = None, 
            content_type: Optional[str] = None):
        """Set cache entry with dynamic TTL."""
        if ttl is None:
            ttl = self._calculate_dynamic_ttl(content_type, value)
        
        self.cache[key] = {
            "value": value,
            "expires_at": datetime.utcnow() + timedelta(seconds=ttl),
            "created_at": datetime.utcnow(),
            "ttl": ttl,
            "access_count": 0,
            "content_type": content_type
        }
    
    def _calculate_dynamic_ttl(self, content_type: str, value: Any) -> int:
        """Calculate TTL based on content characteristics."""
        if content_type == "system_prompt":
            return 3600  # 1 hour for stable content
        elif content_type == "user_context":
            return 600   # 10 minutes for user data
        elif content_type == "real_time_data":
            return 60    # 1 minute for real-time
        else:
            return self.default_ttl

Event-Based Invalidation

class EventBasedCache extends EventEmitter {
  private cache: Map<string, CacheEntry> = new Map();
  private dependencies: Map<string, Set<string>> = new Map();
  
  constructor() {
    super();
    this.setupEventHandlers();
  }
  
  private setupEventHandlers() {
    this.on('invalidate', (event: InvalidationEvent) => {
      this.handleInvalidation(event);
    });
    
    this.on('data_update', (sources: string[]) => {
      this.invalidateDependents(sources);
    });
  }
  
  set(key: string, value: any, dependencies: string[] = []): void {
    const entry: CacheEntry = {
      key,
      value,
      dependencies,
      checksum: this.generateChecksum(value),
      created: new Date(),
      version: this.version
    };
    
    this.cache.set(key, entry);
    
    // Update dependency tracking
    for (const dep of dependencies) {
      if (!this.dependencies.has(dep)) {
        this.dependencies.set(dep, new Set());
      }
      this.dependencies.get(dep)!.add(key);
    }
  }
}

Intelligent ML-Based Invalidation

class IntelligentCacheManager {
  private invalidationModel: any;
  
  async shouldInvalidate(entry: any, age: number): boolean {
    const staleProbability = this.calculateStaleProbability(entry, age);
    const threshold = this.calculateInvalidationThreshold(entry);
    return staleProbability > threshold;
  }
  
  private calculateStaleProbability(entry: any, age: number): number {
    const ageRatio = age / entry.predictedLifetime;
    const accessDecay = Math.exp(-entry.accessCount / 10);
    
    // Content-specific factors
    let contentFactor = 1.0;
    if (entry.features.contentComplexity > 0.8) {
      contentFactor = 0.8; // Complex content changes less
    }
    
    return Math.min(1.0, ageRatio * accessDecay * contentFactor);
  }
}

Performance Testing and Benchmarking

Load Testing Framework

class LoadTester {
  async runLoadTest(config: LoadTestConfig): Promise<LoadTestResults> {
    const results = {
      throughput: [],
      latency: [],
      errors: [],
      resourceUsage: []
    };
    
    // Ramp up load gradually
    for (let users = 1; users <= config.maxUsers; users *= 2) {
      const stageResults = await this.runStage({
        users,
        duration: config.stageDuration,
        scenario: config.scenario
      });
      
      results.throughput.push(stageResults.throughput);
      results.latency.push(stageResults.latency);
      
      // Check for breaking point
      if (stageResults.errorRate > config.errorThreshold) {
        results.breakingPoint = users;
        break;
      }
    }
    
    return results;
  }
}

Performance Regression Detection

class RegressionDetector {
  private baselines = new Map<string, PerformanceBaseline>();
  
  async checkForRegression(metric: string, value: number): Promise<RegressionResult> {
    const baseline = this.baselines.get(metric);
    if (!baseline) {
      return { regression: false, newBaseline: true };
    }
    
    // Statistical significance test
    const zScore = (value - baseline.mean) / baseline.stdDev;
    const pValue = this.calculatePValue(zScore);
    
    if (pValue < 0.05 && value > baseline.mean) {
      return {
        regression: true,
        severity: this.calculateSeverity(value, baseline),
        confidence: 1 - pValue,
        recommendation: this.generateRecommendation(metric, value, baseline)
      };
    }
    
    return { regression: false };
  }
}

k6 Load Testing

// load-test.js
import http from 'k6/http';
import { check, sleep } from 'k6';
import { Rate } from 'k6/metrics';
 
const errorRate = new Rate('errors');
 
export const options = {
  stages: [
    { duration: '2m', target: 100 }, // Ramp up
    { duration: '5m', target: 100 }, // Stay at 100 users
    { duration: '2m', target: 200 }, // Ramp to 200
    { duration: '5m', target: 200 }, // Stay at 200
    { duration: '2m', target: 0 },   // Ramp down
  ],
  thresholds: {
    'http_req_duration': ['p(95)<500'], // 95% under 500ms
    'errors': ['rate<0.1'],             // Error rate under 10%
  },
};
 
export default function() {
  const response = http.get('https://api.example.com/users');
  
  const success = check(response, {
    'status is 200': (r) => r.status === 200,
    'response time < 500ms': (r) => r.timings.duration < 500,
  });
  
  errorRate.add(!success);
  sleep(1);
}

Best Practices Summary

Claude Code Performance Best Practices

1. Strategic Compaction

  • Use /compact at natural breakpoints
  • Monitor context usage proactively
  • Plan sessions around context limits
  • Create checkpoints before compaction

2. Efficient Tool Usage

  • Parallelize independent operations
  • Batch similar tasks together
  • Choose the right tool for each job
  • Cache frequently accessed data

3. CLAUDE.md Optimization

  • Keep it lean and relevant
  • Update frequently with current context
  • Use imports for shared standards
  • Document key decisions and patterns

4. Cost Management

  • Enable prompt caching for stable content
  • Monitor token usage continuously
  • Use appropriate models for each task
  • Implement usage alerts and limits

Application Performance Best Practices

1. Lightweight Instrumentation

// Use sampling for high-frequency operations
const shouldSample = () => Math.random() < 0.01; // 1% sampling
 
// Async metrics collection
const recordMetric = (metric) => {
  setImmediate(() => metricsQueue.push(metric));
};

2. Performance Budgets

const performanceBudgets = {
  task_completion: { p50: 1000, p95: 5000, p99: 10000 },
  token_usage: { per_task: 1000, per_hour: 50000 },
  cost: { per_task: 0.10, per_day: 100 }
};

3. Actionable Alerts

alerts:
  - name: high_token_usage
    condition: "tokens_per_minute > 50000"
    actions:
      - notify: slack
      - auto_remedy: enable_token_optimization

Integration Examples

GitHub Actions Performance Monitoring

name: Performance Monitoring
on:
  workflow_run:
    workflows: ["Claude Code Agent"]
    types: [completed]
 
jobs:
  analyze-performance:
    runs-on: ubuntu-latest
    steps:
      - name: Collect metrics
        run: |
          claude-code metrics export \
            --run-id=${{ github.run_id }} \
            --format=json > metrics.json
      
      - name: Check regression
        run: |
          claude-code metrics analyze \
            --baseline=main \
            --current=metrics.json \
            --fail-on-regression

Real-Time Monitoring Setup

async function setupMonitoring() {
  const collector = new MetricsCollector({
    flushInterval: 1000,
    batchSize: 100
  });
  
  const hooks = [
    {
      name: 'task-performance',
      events: ['task.start', 'task.complete'],
      handler: async (event) => {
        collector.record({
          type: 'task_duration',
          value: event.duration,
          tags: { task: event.taskType }
        });
      }
    }
  ];
  
  await startMonitoring({ collector, hooks });
}

Measuring Success

Key Performance Indicators

  1. Context Efficiency: Average context usage per task < 60%
  2. Token Velocity: Tokens per feature completed
  3. Cache Hit Rate: > 80% for stable content
  4. Response Time: p95 < 5 seconds
  5. Cost per Feature: Track and optimize over time

ROI Calculation

def calculate_optimization_roi(baseline_metrics, optimized_metrics, 
                              implementation_hours=40, developer_rate=150):
    """Calculate ROI for optimization efforts."""
    implementation_cost = implementation_hours * developer_rate
    
    monthly_savings = (baseline_metrics["daily_cost"] - 
                      optimized_metrics["daily_cost"]) * 30
    
    annual_roi = ((monthly_savings * 12 - implementation_cost) / 
                  implementation_cost) * 100
    
    return {
        "monthly_savings": monthly_savings,
        "annual_roi_percent": annual_roi,
        "payback_days": implementation_cost / (monthly_savings / 30)
    }

Conclusion

Performance optimization for Claude Code is a multi-faceted discipline that requires attention to both Claude’s own performance characteristics and the applications you build. By following the patterns and practices in this guide, you can achieve:

  • 90% cost reduction through prompt caching and optimization
  • 85% faster responses with proper context management
  • 10x throughput improvement with parallel processing
  • 60% better resource utilization through intelligent orchestration

Remember that optimization is an iterative process. Start with the quick wins, measure your improvements, and gradually implement more sophisticated optimizations based on your specific needs and usage patterns.

Documentation

External Resources


This comprehensive guide represents the complete state of performance optimization knowledge for Claude Code as of 2025. Continue to monitor the Anthropic documentation for updates and new optimization features.