Claude API Prompt Caching Performance Optimization Guide
Prompt caching is one of the most impactful optimizations you can implement when building production applications with the Claude API. By reusing context that’s been previously processed, you can dramatically reduce latency, lower API costs, and improve the responsiveness of your AI-powered features. This guide walks you through practical strategies for implementing prompt caching effectively.
Understanding How Prompt Caching Works
When you send a request to the Claude API, the model processes the entire prompt—including system instructions, conversation history, and user messages. Without caching, every request must reprocess all this context from scratch. With prompt caching enabled, the API stores previously processed context in a cache, allowing subsequent requests to reference that cached content instead of reprocessing it entirely.
The key insight is that many applications have static or slowly changing context: system prompts, documentation, knowledge bases, and lengthy conversation histories. By identifying these stable elements, you can cache them and only send dynamic content with each request.
Implementing Cache Commands in Your Prompts
The Claude API supports special cache commands that tell the model which parts of your prompt should be cached. These commands use XML-like tags that you include directly in your prompt:
import anthropic
client = anthropic.Anthropic(api_key="your-api-key")
response = client.messages.create(
model="claude-3-5-sonnet-20241022",
max_tokens=1024,
messages=[{
"role": "user",
"content": """Please analyze the following codebase for security vulnerabilities.
<cache>
def authenticate_user(username, password):
# Authentication logic here
pass
def get_user_data(user_id):
# Database query logic
return db.query(f"SELECT * FROM users WHERE id = {user_id}")
</cache>
The above code contains a SQL injection vulnerability in the get_user_data function. Identify all security issues and provide fixes."""
}]
)
The <cache> tags indicate which sections should be stored in the cache. On the first request, the entire prompt is processed. Subsequent requests with the same cached content will be significantly faster because the model only processes the new, uncached portions.
Strategic Caching Patterns for Production
Pattern 1: Knowledge Base Caching
If your application queries against a static knowledge base—product documentation, company policies, or technical specifications—you can cache the entire knowledge base once and only send the user’s specific question:
def create_cachedKnowledge_request(knowledge_base_id, user_question):
"""Create a request with a cached knowledge base."""
# Load the cached knowledge base content
kb_content = load_knowledge_base(knowledge_base_id)
return {
"model": "claude-3-5-sonnet-20241022",
"messages": [{
"role": "user",
"content": f"""<cache>
# Knowledge Base: {knowledge_base_id}
{kb_content}
</cache>
User Question: {user_question}
Provide a concise, accurate answer based on the knowledge base above."""
}]
}
This pattern is particularly effective for customer support applications where the product documentation rarely changes but users ask varied questions.
Pattern 2: System Prompt Caching
Your system prompt—instructions that define the AI’s behavior, tone, and capabilities—remains constant across requests. Cache it once and reuse it:
SYSTEM_PROMPT = """You are a expert code reviewer with 15 years of experience.
- Focus on security, performance, and maintainability
- Provide specific, actionable feedback
- Include code examples when possible
- Never suggest insecure patterns even if asked"""
def create_request(user_message, cached_system=True):
if cached_system:
# Wrap system prompt in cache tags
prompt = f"""<cache>
<system>
{SYSTEM_PROMPT}
</system>
</cache>
{user_message}"""
else:
prompt = f"""<system>
{SYSTEM_PROMPT}
</system>
{user_message}"""
return {
"model": "claude-3-5-sonnet-20241022",
"messages": [{"role": "user", "content": prompt}]
}
Pattern 3: Conversation History Summarization and Caching
For multi-turn conversations, you can periodically summarize and cache the conversation history, keeping only recent messages in full:
def build_conversation_request(conversation_id, current_message):
"""Build a request with cached conversation history."""
# Get cached summary of earlier conversation
historical_summary = get_cached_summary(conversation_id)
# Get recent messages (last 5-10)
recent_messages = get_recent_messages(conversation_id, limit=10)
prompt = f"""<cache>
## Conversation Context (Summary)
{historical_summary}
</cache>
## Recent Conversation
{format_messages(recent_messages)}
## Current Message
User: {current_message}"""
return {
"model": "claude-3-5-sonnet-20241022",
"messages": [{"role": "user", "content": prompt}]
}
Optimizing Cache Performance
Cache Key Strategies
The effectiveness of caching depends on how you structure your cached content. Follow these principles:
-
Minimize variability in cached content: Even small changes to cached sections invalidate the cache. Keep cached content as stable as possible.
-
Separate static from dynamic content: Place system instructions, documentation, and reference material in cache tags. Keep user-specific and task-specific content outside.
-
Use consistent formatting: Cache content should have consistent structure across requests. Variations in whitespace or formatting can affect cache hits.
Monitoring Cache Performance
Track these metrics to understand your caching effectiveness:
def log_cache_metrics(request, response):
"""Log cache-related metrics for analysis."""
metrics = {
"prompt_tokens": response.usage.input_tokens,
"cached_tokens": getattr(response.usage, 'cache_read_input_tokens', 0),
"cache_hit_ratio": (
getattr(response.usage, 'cache_read_input_tokens', 0) /
max(response.usage.input_tokens, 1)
),
"latency_ms": response.response_ms,
"cost": calculate_cost(response.usage)
}
# Send to your metrics backend
send_metrics("claude_api", metrics)
return metrics
A high cache hit ratio (above 70% is excellent) indicates your caching strategy is working well. If hit ratios are low, review what you’re including in cache tags.
Cache Invalidation Strategies
Cached content becomes stale when your underlying data changes. Implement appropriate invalidation:
- Time-based: Refresh cached knowledge bases on a schedule (daily, weekly)
- Event-based: Invalidate caches when underlying data changes
- Version-based: Include version identifiers in cached content to detect staleness
def should_refresh_cache(cache_entry):
"""Determine if cache should be refreshed."""
age_hours = (datetime.now() - cache_entry.updated_at).total_seconds() / 3600
# Refresh knowledge bases daily
if cache_entry.cache_type == "knowledge_base":
return age_hours > 24
# Refresh system prompts weekly
if cache_entry.cache_type == "system_prompt":
return age_hours > 168
return False
Common Pitfalls to Avoid
-
Caching too much dynamic content: If you’re frequently invalidating caches, you’re not gaining the performance benefit. Keep cached sections stable.
-
Ignoring cache costs: While cached tokens are cheaper, they still cost something. Balance cache complexity against actual savings.
-
Not testing cache behavior: Simulate cache hits and misses in your testing to ensure your application handles both scenarios correctly.
-
Forgetting about cache limits: Check API documentation for any limits on cached content size or number of cache entries.
Conclusion
Prompt caching is a powerful optimization that can reduce API costs by 30-70% while improving response times. The key is identifying the stable, reusable components of your prompts—system instructions, documentation, knowledge bases—and strategically caching them. Implement the patterns in this guide, monitor your cache hit ratios, and adjust your approach based on actual production data.
Start with simple caching of your system prompts, then expand to knowledge base and conversation history caching as you become more comfortable with the patterns. Your users will appreciate the faster responses, and your infrastructure costs will thank you.
Related Reading
- Claude Code for Beginners: Complete Getting Started Guide
- Best Claude Skills for Developers in 2026
- Claude Skills Guides Hub
Built by theluckystrike — More at zovo.one