Advanced Claude API Optimization & Token Management

Advanced techniques for maximizing Prompt Cache efficiency, optimizing token billing, managing long context windows, and implementing robust retry logic.

Based on community reports and public reverse-engineering. Not checked against Anthropic documentation item by item; confirm important details on the official Help Center.

Educational and diagnostic content: it explains how risk signals work so you can understand and troubleshoot your own setup. It is not advice to break any rules. Follow Anthropic’s Usage Policy and Terms of Service and the laws where you live; if your region is not supported, use an officially available alternative.

On this page

1. Prompt Cache Principles & Maximization

Anthropic's Prompt Caching feature can reduce costs by 90% and latency by 85% for repeated context. Understanding cache behavior is critical for API optimization:

Cache Behavior Rules

  • Minimum Cache Size: Cached blocks must be ≥ 1024 tokens. Smaller blocks are not cached.
  • Cache TTL: Cached content expires after 5 minutes of inactivity. Re-using the same cache within 5 minutes extends the TTL.
  • Cache Key: Cache is keyed by exact content match. Changing a single character invalidates the cache.
  • Cache Placement: Only system role messages and the final user message support caching. Intermediate messages cannot be cached.

Optimal Cache Strategy

const systemPrompt = `You are an expert software architect...
[Large 5000-token context that rarely changes]`;

// Mark system prompt for caching
const response = await anthropic.messages.create({
  model: "claude-sonnet-4.5-high",
  max_tokens: 2048,
  system: [
    {
      type: "text",
      text: systemPrompt,
      cache_control: { type: "ephemeral" }, // Cache this block
    },
  ],
  messages: [
    { role: "user", content: "Refactor this function..." },
  ],
});

2. Token Billing Optimization & Context Management

Claude API pricing is asymmetric: input tokens cost less than output tokens, and cached tokens cost 90% less than input tokens. Structure conversations to maximize caching:

Cost Comparison (Claude Sonnet 4.5 High)

Token Type Cost per 1M Tokens Relative Cost
Output Tokens $15.00 100x
Input Tokens $3.00 20x
Cached Input Tokens $0.30 2x
Cache Write Tokens $3.75 25x

Long Context Window Management

// Sliding window approach for multi-turn conversations
function maintainContextWindow(history: Message[], maxTokens: number = 180000) {
  let totalTokens = estimateTokenCount(history);
  
  while (totalTokens > maxTokens && history.length > 2) {
    // Remove oldest non-system messages first
    history.splice(1, 2); // Remove one user-assistant pair
    totalTokens = estimateTokenCount(history);
  }
  
  return history;
}

3. Concurrency Control & Rate Limit Handling

Anthropic enforces organization-level rate limits. Implement client-side concurrency control to avoid 429 errors:

Token Bucket Rate Limiter

class RateLimiter {
  private tokens: number;
  private lastRefill: number;
  private refillRate: number; // tokens per second
  private capacity: number;

  constructor(requestsPerMinute: number) {
    this.capacity = requestsPerMinute;
    this.tokens = requestsPerMinute;
    this.lastRefill = Date.now();
    this.refillRate = requestsPerMinute / 60;
  }

  async acquire(): Promise {
    this.refill();
    
    while (this.tokens < 1) {
      const waitTime = (1 - this.tokens) / this.refillRate * 1000;
      await new Promise(resolve => setTimeout(resolve, waitTime));
      this.refill();
    }
    
    this.tokens -= 1;
  }

  private refill(): void {
    const now = Date.now();
    const elapsed = (now - this.lastRefill) / 1000;
    this.tokens = Math.min(this.capacity, this.tokens + elapsed * this.refillRate);
    this.lastRefill = now;
  }
}

const limiter = new RateLimiter(50); // 50 requests per minute

async function callClaude(prompt: string) {
  await limiter.acquire();
  return await anthropic.messages.create({...});
}

4. Streaming Output & Retry Best Practices

Streaming responses reduce time-to-first-token and enable progressive rendering. Combine with exponential backoff for robust error handling:

Streaming with Retry Logic

async function* streamWithRetry(prompt: string, maxRetries = 3) {
  for (let attempt = 0; attempt < maxRetries; attempt++) {
    try {
      const stream = await anthropic.messages.stream({
        model: "claude-sonnet-4.5-high",
        max_tokens: 4096,
        messages: [{ role: "user", content: prompt }],
      });

      for await (const chunk of stream) {
        if (chunk.type === "content_block_delta") {
          yield chunk.delta.text;
        }
      }
      
      return; // Success, exit retry loop
      
    } catch (error: any) {
      if (error.status === 529 && attempt < maxRetries - 1) {
        // Overloaded error, retry with backoff
        const delay = Math.min(1000 * Math.pow(2, attempt), 30000);
        await new Promise(resolve => setTimeout(resolve, delay));
      } else {
        throw error;
      }
    }
  }
}