Performance Optimization Patterns

Welcome to the comprehensive performance optimization guide for Claude Code. This section consolidates all performance optimization strategies, from managing Claude Code’s own resources to optimizing the applications you build.

🎯 Quick Navigation

Core Resources

Claude Code Performance

Application Performance

📊 Optimization Metrics Dashboard

Track these key metrics for optimal performance:

MetricTargetTool
Token Usage< 80% of limit/usage
Response Time< 3s averagePerformance logs
Context Size< 50% of window/memory
Error Rate< 1%Error tracking

Claude Code Performance Optimization

Context Window Management

Understanding Context Windows

Claude Code operates within a context window that includes:

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

The /compact Command

The /compact command is Claude Code’s most powerful context management feature:

# Compact the current conversation
/compact
 
# Why use it:
# - Preserves critical information while removing redundancy
# - Immediately frees up context space
# - Maintains conversation continuity
# - Reduces token usage and costs

Real-time Context Visibility

Monitor your context usage in real-time:

# Track token usage
npx cc usage
 
# View current context size
# (Displayed in Claude Code interface)

Context Management Strategies

1. Proactive Compaction

Best practice: Use /compact when:
- Context usage exceeds 60%
- Before starting new complex tasks
- After completing major milestones
- When switching between different parts of a project

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

## CLAUDE.md Best Practices
 
Include in CLAUDE.md:
- Project architecture overview
- Key file locations
- Common commands
- Coding standards
- Performance considerations
 
Exclude from CLAUDE.md:
- Detailed implementation code
- Large configuration examples
- Verbose documentation
- Historical change logs

Memory Usage Optimization

Environment Configuration

Configure Claude Code for optimal memory usage:

# Set Node.js memory limit (in devcontainer.json or .env)
export NODE_OPTIONS="--max-old-space-size=4096"
 
# Configure bash timeouts to prevent hung processes
export BASH_DEFAULT_TIMEOUT_MS=120000  # 2 minutes
export BASH_MAX_TIMEOUT_MS=600000      # 10 minutes
 
# Maintain consistent working directory
export CLAUDE_BASH_MAINTAIN_PROJECT_WORKING_DIR=true

Shell Snapshot Management

Claude Code uses in-memory shell snapshots stored in ~/.claude:

# Monitor snapshot size
du -sh ~/.claude
 
# Clean old snapshots if needed
find ~/.claude -type f -mtime +7 -delete

Auto-Compaction Settings

Claude Code auto-compacts at 80% context usage. Monitor and adjust your workflow:

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

Tool Call Optimization

Parallel Tool Execution

Maximize performance with parallel tool calls:

// 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

Use multi-edit and 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 Optimization

Choose the right search tool for the 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 all REST API endpoint definitions"
});

Response Time Improvements

Thinking Mode Optimization

Use appropriate thinking levels for different tasks:

## Thinking Mode Guide
 
1. **No thinking keyword**: Simple, straightforward tasks
   - File reads, basic edits, simple searches
 
2. **"think"**: Moderate complexity
   - Design decisions, algorithm choices
 
3. **"think hard"**: Complex problems
   - Architecture design, performance optimization
 
4. **"think harder"**: Very complex challenges
   - Multi-system integration, complex debugging
 
5. **"ultrathink"**: Extreme complexity
   - Novel algorithm design, critical system decisions

Prompt Optimization

Write efficient prompts:

## 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

Load only necessary context:

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

Resource Monitoring

Token Usage Tracking

Monitor and analyze token consumption:

# Check current usage
npx cc usage
 
# Export usage data for analysis
npx cc usage --export usage-report.json

Performance Metrics

Track key performance indicators:

interface PerformanceMetrics {
  contextUsage: number;      // Percentage of context used
  responseTime: number;      // Average response time
  toolCallCount: number;     // Number of tool calls
  compactionCount: number;   // Times /compact used
  sessionDuration: number;   // Total session time
}
 
// Log metrics for optimization
function logMetrics(metrics: PerformanceMetrics) {
  console.log('Performance Report:', {
    ...metrics,
    efficiency: metrics.toolCallCount / metrics.sessionDuration
  });
}

Memory Profiling

Monitor Claude Code memory usage:

# Check Node.js memory usage
ps aux | grep claude-code
 
# Monitor in real-time
top -p $(pgrep -f claude-code)

Cost Optimization

Token-Efficient Patterns

Minimize token usage while maintaining quality:

// 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
// When dealing with large API responses or logs
const summary = await task({
  prompt: "Summarize key errors from this log",
  content: largeLogFile
});

Subscription Optimization

Choose the right usage pattern:

## Usage Patterns
 
### Burst Usage (Development)
- Compact frequently
- Use specific, focused prompts
- Batch similar tasks together
- Clear context between projects
 
### Sustained Usage (Production)
- Implement CLAUDE.md for persistent context
- Use /compact strategically
- Monitor usage trends
- Set up usage alerts

Context Budget Management

Allocate context budget effectively:

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;
  }
}

Best Practices

1. Strategic Compaction

Compact at these checkpoints:
- [ ] After completing major features
- [ ] Before starting debugging sessions
- [ ] When switching project contexts
- [ ] Before large file operations
- [ ] At natural task boundaries

2. Efficient File Management

// Group related file operations
const projectFiles = await Promise.all([
  read('src/index.ts'),
  read('src/config.ts'),
  read('package.json')
]);
 
// Use glob for bulk operations
const testFiles = await glob('**/*.test.ts');

3. CLAUDE.md Optimization

## CLAUDE.md Template
 
### Project Overview
[2-3 sentences max]
 
### Key Locations
- API: `/src/api`
- Tests: `/tests`
- Config: `/config`
 
### Common Commands
```bash
npm run dev      # Start development
npm test         # Run tests
npm run build    # Build project

Performance Notes

  • Large files: data/*.json (use pagination)
  • Slow operations: Database migrations
  • Memory intensive: Image processing

### 4. **Session Management**
```typescript
// Plan sessions for optimal performance
interface SessionPlan {
  tasks: string[];
  compactionPoints: number[];
  estimatedTokens: number;
}

function planSession(tasks: string[]): SessionPlan {
  const plan = {
    tasks,
    compactionPoints: [],
    estimatedTokens: 0
  };
  
  // Add compaction after every 3 major tasks
  for (let i = 3; i < tasks.length; i += 3) {
    plan.compactionPoints.push(i);
  }
  
  return plan;
}

5. Tool Selection Guide

## When to use each tool:
 
### Read
- Specific file contents
- Configuration files
- Small to medium files
 
### Glob
- Finding files by pattern
- Exploring project structure
- Bulk file operations
 
### Grep
- Searching for specific content
- Finding usage patterns
- Quick content checks
 
### Task
- Complex multi-step searches
- When unsure of file locations
- Exploratory analysis
 
### Bash
- System commands
- Build/test execution
- Git operations

Advanced Techniques

Long-Term Context Management Protocol (LTCMP)

Implement systematic context preservation:

interface ContextSnapshot {
  timestamp: Date;
  keyInsights: string[];
  completedTasks: string[];
  pendingWork: string[];
  contextUsage: number;
}
 
class LTCMPManager {
  async saveSnapshot(): Promise<void> {
    const snapshot: ContextSnapshot = {
      timestamp: new Date(),
      keyInsights: this.extractKeyInsights(),
      completedTasks: this.getCompletedTasks(),
      pendingWork: this.getPendingWork(),
      contextUsage: this.getContextUsage()
    };
    
    await write('.claude/snapshots/session-${Date.now()}.json', 
                JSON.stringify(snapshot, null, 2));
  }
  
  async loadPreviousContext(): Promise<ContextSnapshot> {
    const snapshots = await glob('.claude/snapshots/*.json');
    const latest = snapshots.sort().pop();
    return JSON.parse(await read(latest));
  }
}

Predictive Compaction

Anticipate when compaction will be needed:

class PredictiveCompactor {
  private usageHistory: number[] = [];
  
  recordUsage(percentage: number): void {
    this.usageHistory.push(percentage);
    if (this.usageHistory.length > 10) {
      this.usageHistory.shift();
    }
  }
  
  shouldCompactSoon(): boolean {
    if (this.usageHistory.length < 3) return false;
    
    // Calculate usage trend
    const trend = this.calculateTrend();
    const currentUsage = this.usageHistory[this.usageHistory.length - 1];
    
    // Predict next usage
    const predictedUsage = currentUsage + trend;
    
    // Recommend compaction if predicted > 75%
    return predictedUsage > 75;
  }
  
  private calculateTrend(): number {
    // Simple linear trend
    const recent = this.usageHistory.slice(-3);
    return (recent[2] - recent[0]) / 2;
  }
}

Application Performance Optimization Workflows

Memory Profiling and Optimization

Workflow Steps

  1. Initial Memory Baseline

    // Step 1: Capture baseline memory usage
    console.log('Initial memory:', process.memoryUsage());
     
    // Step 2: Set up periodic memory monitoring
    setInterval(() => {
      const usage = process.memoryUsage();
      console.log(`Memory: RSS ${usage.rss / 1024 / 1024} MB, Heap ${usage.heapUsed / 1024 / 1024} MB`);
    }, 5000);
  2. Connect Chrome DevTools

    # Start Node.js with inspector
    node --inspect server.js
     
    # Open chrome://inspect in Chrome browser
    # Take initial heap snapshot
  3. Identify Memory Leaks

    • Take heap snapshot before operation
    • Perform the suspected leaky operation multiple times
    • Take heap snapshot after operation
    • Compare snapshots to identify growing objects
  4. Common Memory Leak Patterns to Check

    • Event Listeners: Check for unremoved listeners

      // Bad
      emitter.on('data', handler);
       
      // Good
      emitter.on('data', handler);
      // Later...
      emitter.removeListener('data', handler);
    • Closures Holding State: Review nested closures

      // Problematic closure pattern
      function createLeak() {
        const largeData = new Array(1000000);
        return function() {
          // This closure keeps largeData in memory
          console.log(largeData.length);
        };
      }
    • Unbounded Caches: Implement eviction strategies

      // Use LRU cache with max size
      const LRU = require('lru-cache');
      const cache = new LRU({ max: 500 });
  5. Optimization Techniques

    • Implement object pooling for frequently created objects
    • Use streams for large data processing
    • Enable V8 optimizations with proper coding patterns
    • Minimize object allocations in hot code paths
  6. Verification

    • Run stress tests and monitor memory usage
    • Ensure garbage collection time remains under 50ms
    • Verify memory usage stabilizes over time

Tools to Use

  • Chrome DevTools Memory Profiler
  • Node.js built-in profiler (--prof flag)
  • Clinic.js for automated profiling
  • Process.memoryUsage() for monitoring

Database Query Optimization

PostgreSQL Optimization Workflow

  1. Analyze Current Performance

    -- Enable query timing
    \timing on
     
    -- Check slow queries
    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 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. Query Rewriting

    • Replace subqueries with JOINs where appropriate
    • Use CTEs for complex queries
    • Implement proper pagination with LIMIT/OFFSET
    • Consider materialized views for complex aggregations
  5. Statistics and Maintenance

    -- Update statistics
    ANALYZE orders;
     
    -- Check table bloat
    SELECT schemaname, tablename, 
           pg_size_pretty(pg_total_relation_size(schemaname||'.'||tablename)) as size
    FROM pg_tables
    ORDER BY pg_total_relation_size(schemaname||'.'||tablename) DESC
    LIMIT 20;
     
    -- Vacuum if needed
    VACUUM ANALYZE orders;

MySQL Optimization Workflow

  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
    • OLAP: Larger buffer pool, optimize for reads

Frontend Bundle Size Reduction

Modern Build Tool Optimization Workflow

  1. Analyze Current Bundle

    # For Vite
    npm run build -- --report
     
    # For Webpack
    npm install --save-dev webpack-bundle-analyzer
    webpack --profile --json > stats.json
    webpack-bundle-analyzer stats.json
  2. Enable Tree Shaking

    // vite.config.js
    export default {
      build: {
        rollupOptions: {
          treeshake: {
            moduleSideEffects: false,
            propertyReadSideEffects: false,
            tryCatchDeoptimization: false
          }
        }
      }
    }
     
    // webpack.config.js
    module.exports = {
      mode: 'production', // Enables tree shaking
      optimization: {
        usedExports: true,
        minimize: true,
        sideEffects: false
      }
    };
  3. Implement Code Splitting

    // Route-based splitting
    const Dashboard = lazy(() => import('./Dashboard'));
    const Analytics = lazy(() => import('./Analytics'));
     
    // Component-based splitting
    const HeavyComponent = lazy(() => 
      import(/* webpackChunkName: "heavy" */ './HeavyComponent')
    );
  4. Optimize Dependencies

    // Replace heavy libraries with lighter alternatives
    // 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);
      };
    };
  5. Vendor Splitting

    // vite.config.js
    build: {
      rollupOptions: {
        output: {
          manualChunks: {
            vendor: ['react', 'react-dom'],
            ui: ['@mui/material'],
            utils: ['lodash-es', 'date-fns']
          }
        }
      }
    }
  6. Monitor Bundle Size

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

API Response Time Improvements

Optimization Workflow

  1. Implement Request-Level Monitoring

    // Express middleware for timing
    app.use((req, res, next) => {
      const start = process.hrtime.bigint();
      
      res.on('finish', () => {
        const duration = Number(process.hrtime.bigint() - start) / 1000000;
        console.log(`${req.method} ${req.path} - ${duration}ms`);
      });
      
      next();
    });
  2. Database Query Optimization

    // Add query timing
    const { Client } = require('pg');
    const client = new Client();
     
    client.query = (function(originalQuery) {
      return async function(...args) {
        const start = Date.now();
        try {
          const result = await originalQuery.apply(this, args);
          const duration = Date.now() - start;
          if (duration > 100) {
            console.warn(`Slow query (${duration}ms):`, args[0]);
          }
          return result;
        } catch (error) {
          throw error;
        }
      };
    })(client.query.bind(client));
  3. Implement Caching Layers

    // Memory cache for hot data
    const NodeCache = require('node-cache');
    const cache = new NodeCache({ stdTTL: 600 });
     
    // Redis for distributed cache
    const redis = require('redis');
    const client = redis.createClient();
     
    async function getCachedData(key, fetchFn) {
      // Check memory cache first
      let data = cache.get(key);
      if (data) return data;
      
      // Check Redis
      data = await client.get(key);
      if (data) {
        cache.set(key, JSON.parse(data));
        return JSON.parse(data);
      }
      
      // Fetch from source
      data = await fetchFn();
      
      // Store in both caches
      cache.set(key, data);
      await client.setex(key, 3600, JSON.stringify(data));
      
      return data;
    }
  4. Optimize Payload Size

    // Enable compression
    const compression = require('compression');
    app.use(compression());
     
    // Implement field filtering
    app.get('/api/users', (req, res) => {
      const fields = req.query.fields?.split(',') || [];
      const users = getUsers();
      
      if (fields.length > 0) {
        const filtered = users.map(user => 
          fields.reduce((obj, field) => {
            obj[field] = user[field];
            return obj;
          }, {})
        );
        res.json(filtered);
      } else {
        res.json(users);
      }
    });
  5. Implement CDN and Edge Computing

    // Configure CDN headers
    app.use((req, res, next) => {
      if (req.path.startsWith('/static/')) {
        res.set('Cache-Control', 'public, max-age=31536000');
      } else if (req.path.startsWith('/api/')) {
        res.set('Cache-Control', 'private, max-age=0');
      }
      next();
    });
     
    // Edge function example (Cloudflare Workers)
    addEventListener('fetch', event => {
      event.respondWith(handleRequest(event.request));
    });
     
    async function handleRequest(request) {
      const cache = caches.default;
      let response = await cache.match(request);
      
      if (!response) {
        response = await fetch(request);
        if (response.status === 200) {
          const headers = new Headers(response.headers);
          headers.set('Cache-Control', 'max-age=300');
          response = new Response(response.body, {
            status: response.status,
            statusText: response.statusText,
            headers: headers
          });
          event.waitUntil(cache.put(request, response.clone()));
        }
      }
      
      return response;
    }

Automated Performance Regression Detection

CI/CD Integration Workflow

  1. Set Up Lighthouse CI

    # .github/workflows/lighthouse.yml
    name: Lighthouse CI
    on: [push, pull_request]
     
    jobs:
      lighthouse:
        runs-on: ubuntu-latest
        steps:
          - uses: actions/checkout@v3
          - uses: actions/setup-node@v3
          - run: npm ci
          - run: npm run build
          
          - name: Run Lighthouse CI
            uses: treosh/lighthouse-ci-action@v9
            with:
              configPath: './lighthouserc.json'
              uploadArtifacts: true
              temporaryPublicStorage: true
  2. Configure Performance Budgets

    // lighthouserc.json
    {
      "ci": {
        "collect": {
          "numberOfRuns": 3,
          "startServerCommand": "npm run serve",
          "url": ["http://localhost:3000"]
        },
        "assert": {
          "preset": "lighthouse:recommended",
          "assertions": {
            "categories:performance": ["error", {"minScore": 0.9}],
            "first-contentful-paint": ["error", {"maxNumericValue": 2000}],
            "largest-contentful-paint": ["error", {"maxNumericValue": 2500}],
            "total-blocking-time": ["error", {"maxNumericValue": 300}],
            "cumulative-layout-shift": ["error", {"maxNumericValue": 0.1}],
            "interactive": ["error", {"maxNumericValue": 3500}]
          }
        },
        "upload": {
          "target": "temporary-public-storage"
        }
      }
    }
  3. Web Vitals Monitoring

    // Install: npm install web-vitals
    import { getCLS, getFID, getFCP, getLCP, getTTFB } from 'web-vitals';
     
    function sendToAnalytics(metric) {
      // Send to your analytics endpoint
      fetch('/api/metrics', {
        method: 'POST',
        body: JSON.stringify({
          name: metric.name,
          value: metric.value,
          delta: metric.delta,
          id: metric.id,
          url: window.location.href,
          timestamp: Date.now()
        }),
        headers: { 'Content-Type': 'application/json' }
      });
    }
     
    getCLS(sendToAnalytics);
    getFID(sendToAnalytics);
    getFCP(sendToAnalytics);
    getLCP(sendToAnalytics);
    getTTFB(sendToAnalytics);
  4. Custom Performance Metrics

    // Track custom business metrics
    class PerformanceTracker {
      constructor() {
        this.marks = new Map();
      }
      
      start(name) {
        this.marks.set(name, performance.now());
      }
      
      end(name, threshold) {
        const start = this.marks.get(name);
        if (!start) return;
        
        const duration = performance.now() - start;
        this.marks.delete(name);
        
        // Log if exceeds threshold
        if (threshold && duration > threshold) {
          console.warn(`Performance regression: ${name} took ${duration}ms (threshold: ${threshold}ms)`);
        }
        
        // Send to monitoring
        this.report(name, duration);
      }
      
      report(name, duration) {
        if ('sendBeacon' in navigator) {
          navigator.sendBeacon('/api/performance', JSON.stringify({
            metric: name,
            duration,
            timestamp: Date.now()
          }));
        }
      }
    }
     
    const perf = new PerformanceTracker();
     
    // Usage
    perf.start('api-call');
    const data = await fetchData();
    perf.end('api-call', 1000); // Alert if > 1 second

Performance Monitoring Integration

APM Tool Integration Workflow

  1. DataDog Integration

    // Install: npm install dd-trace
    const tracer = require('dd-trace').init({
      service: 'my-app',
      env: process.env.NODE_ENV,
      version: process.env.APP_VERSION,
      analytics: true,
      profiling: true,
      logInjection: true
    });
     
    // Automatic instrumentation
    tracer.use('express');
    tracer.use('pg');
    tracer.use('redis');
     
    // Custom spans
    app.get('/api/complex-operation', async (req, res) => {
      const span = tracer.startSpan('complex.operation');
      
      try {
        span.setTag('user.id', req.user.id);
        
        const dbSpan = tracer.startSpan('database.query', {
          childOf: span
        });
        const data = await db.query('SELECT ...');
        dbSpan.finish();
        
        const processSpan = tracer.startSpan('data.processing', {
          childOf: span
        });
        const result = processData(data);
        processSpan.finish();
        
        res.json(result);
      } catch (error) {
        span.setTag('error', true);
        span.setTag('error.message', error.message);
        throw error;
      } finally {
        span.finish();
      }
    });
  2. New Relic Integration

    // newrelic.js
    exports.config = {
      app_name: ['My Application'],
      license_key: process.env.NEW_RELIC_LICENSE_KEY,
      logging: {
        level: 'info'
      },
      distributed_tracing: {
        enabled: true
      },
      transaction_tracer: {
        enabled: true,
        transaction_threshold: 'apdex_f',
        record_sql: 'obfuscated'
      }
    };
     
    // app.js
    require('newrelic');
     
    // Custom instrumentation
    const newrelic = require('newrelic');
     
    app.get('/api/users/:id', (req, res) => {
      newrelic.addCustomAttribute('user.id', req.params.id);
      newrelic.addCustomAttribute('api.version', 'v2');
      
      // Custom metric
      newrelic.recordMetric('Custom/UserAPI/RequestCount', 1);
      
      // Custom event
      newrelic.recordCustomEvent('UserAPIAccess', {
        userId: req.params.id,
        endpoint: req.path,
        method: req.method
      });
    });
  3. Sentry Performance Monitoring

    // Install: npm install @sentry/node @sentry/tracing
    const Sentry = require('@sentry/node');
    const { ProfilingIntegration } = require('@sentry/profiling-node');
     
    Sentry.init({
      dsn: process.env.SENTRY_DSN,
      integrations: [
        new Sentry.Integrations.Http({ tracing: true }),
        new Sentry.Integrations.Express({ app }),
        new ProfilingIntegration()
      ],
      tracesSampleRate: 1.0,
      profilesSampleRate: 1.0
    });
     
    // Transaction monitoring
    app.use(Sentry.Handlers.requestHandler());
    app.use(Sentry.Handlers.tracingHandler());
     
    // Custom performance tracking
    app.post('/api/process', async (req, res) => {
      const transaction = Sentry.getCurrentHub()
        .getScope()
        .getTransaction();
      
      const span = transaction.startChild({
        op: 'task',
        description: 'Process user data'
      });
      
      try {
        const result = await processUserData(req.body);
        span.setStatus('ok');
        res.json(result);
      } catch (error) {
        span.setStatus('internal_error');
        throw error;
      } finally {
        span.finish();
      }
    });

Load Testing Automation

k6 Load Testing Workflow

  1. Create Test Script

    // 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 up to 200
        { duration: '5m', target: 200 }, // Stay at 200
        { duration: '2m', target: 0 },   // Ramp down
      ],
      thresholds: {
        'http_req_duration': ['p(95)<500'], // 95% of requests 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);
    }
  2. CI/CD Integration

    # .github/workflows/load-test.yml
    name: Load Testing
    on:
      schedule:
        - cron: '0 2 * * *' # Daily at 2 AM
      workflow_dispatch:
     
    jobs:
      k6-load-test:
        runs-on: ubuntu-latest
        steps:
          - uses: actions/checkout@v3
          
          - name: Run k6 test
            uses: grafana/k6-action@v0.2.0
            with:
              filename: load-test.js
              flags: --out json=results.json
          
          - name: Upload results
            uses: actions/upload-artifact@v3
            with:
              name: k6-results
              path: results.json
          
          - name: Check thresholds
            run: |
              if grep -q '"passes":false' results.json; then
                echo "Load test failed thresholds"
                exit 1
              fi

Artillery Load Testing Workflow

  1. Create Test Configuration

    # load-test.yml
    config:
      target: "https://api.example.com"
      phases:
        - duration: 60
          arrivalRate: 10
          name: "Warm up"
        - duration: 300
          arrivalRate: 50
          name: "Sustained load"
        - duration: 60
          arrivalRate: 100
          name: "Peak load"
      processor: "./processors.js"
      payload:
        path: "./users.csv"
        fields:
          - "userId"
          - "email"
     
    scenarios:
      - name: "User Journey"
        flow:
          - post:
              url: "/auth/login"
              json:
                email: "{{ email }}"
                password: "password123"
              capture:
                - json: "$.token"
                  as: "authToken"
          
          - get:
              url: "/users/{{ userId }}"
              headers:
                Authorization: "Bearer {{ authToken }}"
              expect:
                - statusCode: 200
                - contentType: json
                - hasProperty: "id"
          
          - think: 5
          
          - post:
              url: "/users/{{ userId }}/actions"
              headers:
                Authorization: "Bearer {{ authToken }}"
              json:
                action: "update_profile"
              expect:
                - statusCode:
                    - 200
                    - 201
  2. Run with Performance Thresholds

    # Run test with thresholds
    artillery run load-test.yml --output results.json
     
    # Generate report
    artillery report results.json --output report.html

Caching Strategies Implementation

Redis Caching Implementation Workflow

  1. Set Up Caching Infrastructure

    // cache.js
    const Redis = require('ioredis');
    const redis = new Redis({
      host: process.env.REDIS_HOST,
      port: process.env.REDIS_PORT,
      password: process.env.REDIS_PASSWORD,
      retryStrategy: (times) => Math.min(times * 50, 2000)
    });
     
    class CacheManager {
      constructor(defaultTTL = 3600) {
        this.defaultTTL = defaultTTL;
        this.redis = redis;
      }
      
      async get(key) {
        try {
          const value = await this.redis.get(key);
          return value ? JSON.parse(value) : null;
        } catch (error) {
          console.error('Cache get error:', error);
          return null;
        }
      }
      
      async set(key, value, ttl = this.defaultTTL) {
        try {
          await this.redis.setex(
            key,
            ttl,
            JSON.stringify(value)
          );
        } catch (error) {
          console.error('Cache set error:', error);
        }
      }
      
      async invalidate(pattern) {
        const keys = await this.redis.keys(pattern);
        if (keys.length > 0) {
          await this.redis.del(...keys);
        }
      }
      
      // Implement 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;
      }
      
      // Implement write-through pattern
      async writeThrough(key, value, writeFn, ttl = this.defaultTTL) {
        await writeFn(value);
        await this.set(key, value, ttl);
        return value;
      }
    }
     
    module.exports = new CacheManager();
  2. Implement Distributed Caching for Microservices

    // Shared cache strategy
    const cache = require('./cache');
     
    // Service A
    app.get('/api/products/:id', async (req, res) => {
      const key = `product:${req.params.id}`;
      
      const product = await cache.getOrSet(key, async () => {
        return await db.query('SELECT * FROM products WHERE id = ?', [req.params.id]);
      }, 3600);
      
      res.json(product);
    });
     
    // Service B (can access same cached data)
    app.get('/api/cart/products/:id', async (req, res) => {
      const key = `product:${req.params.id}`;
      const product = await cache.get(key);
      
      if (product) {
        res.json({ cached: true, product });
      } else {
        // Fetch from Service A or database
        const product = await fetchProduct(req.params.id);
        res.json({ cached: false, product });
      }
    });
  3. Advanced Caching Patterns

    // Tag-based cache invalidation
    class TaggedCache extends CacheManager {
      async setWithTags(key, value, tags, ttl = this.defaultTTL) {
        await this.set(key, value, ttl);
        
        // Store tags
        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}`);
        }
      }
    }
     
    // Usage
    const taggedCache = new TaggedCache();
     
    // Cache with tags
    await taggedCache.setWithTags(
      'user:123:profile',
      userData,
      ['user:123', 'profiles'],
      3600
    );
     
    // Invalidate all user:123 related cache
    await taggedCache.invalidateByTag('user:123');
  4. Multi-Layer Caching

    const NodeCache = require('node-cache');
    const memoryCache = new NodeCache({ stdTTL: 60 });
     
    class MultiLayerCache {
      constructor(redisCache) {
        this.memory = memoryCache;
        this.redis = redisCache;
      }
      
      async get(key) {
        // Check memory cache first
        let value = this.memory.get(key);
        if (value !== undefined) {
          return value;
        }
        
        // Check Redis
        value = await this.redis.get(key);
        if (value !== null) {
          // Store in memory cache
          this.memory.set(key, value);
          return value;
        }
        
        return null;
      }
      
      async set(key, value, ttl = 3600) {
        // Set in both caches
        this.memory.set(key, value, Math.min(ttl, 300)); // Max 5 min in memory
        await this.redis.set(key, value, ttl);
      }
    }
  5. Cache Warming and Preloading

    // Implement cache warming
    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}`);
        
        for (const key of task.keys) {
          try {
            const value = await task.fetchFn(key);
            await this.cache.set(key, value);
          } catch (error) {
            console.error(`Failed to warm cache for ${key}:`, error);
          }
        }
      }
      
      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();

Summary

This comprehensive guide provides systematic approaches for optimizing both Claude Code performance and application performance. Key takeaways:

For Claude Code Performance:

  1. Proactive context management using /compact and monitoring
  2. Efficient tool usage with parallel execution and batching
  3. Strategic resource allocation based on task requirements
  4. Continuous monitoring of usage patterns and costs
  5. Systematic workflows that incorporate optimization checkpoints

For Application Performance:

  1. Detection Methods: How to identify performance problems
  2. Analysis Tools: Specific tools and commands to use
  3. Implementation Steps: Detailed code examples and configurations
  4. Verification Procedures: How to confirm improvements
  5. Monitoring Integration: Ongoing performance tracking

By following these patterns and workflows, developers can maximize Claude Code’s capabilities while maintaining optimal performance and managing costs effectively.

Documentation

Experiments

External Resources

Verifications

This document was last verified on 2025-07-21. The information was verified against:

  1. Claude Code Memory Management: Confirmed from official Anthropic documentation that Claude Code uses CLAUDE.md files for memory management, with project-level and user-level memory support
  2. /compact Command: Verified from multiple sources including bgadoci.com that /compact is Claude Code’s key context management feature, with automatic compaction now available when approaching context limits
  3. Context Window Details: Confirmed that Claude Sonnet 4 and Opus 4 both have 200k token context windows, with real-time usage indicators showing percentage of context used

Original sources:

🧭 Quick Navigation

← Back to Patterns | Architecture | Testing | Workflows