Production LLM applications must manage costs, leverage caching for efficiency, handle rate limits gracefully, and use the Batch API for high-volume workloads. This lesson covers the economics and operational patterns of Claude at scale.
Claude uses per-token pricing with separate rates for input and output tokens.
| Model | Input (per MTok) | Output (per MTok) |
|---|---|---|
| Claude Opus 4 | $15 | $75 |
| Claude Sonnet 4 | $3 | $15 |
| Claude Haiku 3.5 | $0.80 | $4 |
MTok = million tokens. Output tokens cost 5× more than input tokens because generation is more compute-intensive than processing input.
Key insight: A long system prompt read many times is expensive. If 2,000 tokens of system prompt are sent 1,000 times with Sonnet, that is 2M input tokens = $6. With caching, the same cost drops to ~$0.60.
Prompt caching lets you cache frequently reused prefixes (system prompts, long documents, tool definitions) so you pay a reduced rate on subsequent requests.
response = client.messages.create(
model="claude-sonnet-4-20250514",
max_tokens=1024,
system=[{
"type": "text",
"text": LONG_SYSTEM_PROMPT, # 2000+ tokens
"cache_control": {"type": "ephemeral"}
}],
messages=[{"role": "user", "content": "Hello!"}]
)
Important rules for prompt caching:
For workloads that do not need real-time responses, the Batch API offers 50% cost savings with a 24-hour SLA.
batch = client.messages.batches.create(
requests=[
{
"custom_id": f"task-{i}",
"params": {
"model": "claude-sonnet-4-20250514",
"max_tokens": 1024,
"messages": [{"role": "user", "content": task}],
}
}
for i, task in enumerate(tasks)
]
)
print(f"Batch ID: {batch.id}") # Poll for results
Use cases: Classification of large datasets, generating summaries for a document collection, evaluating model outputs, bulk data extraction. Any workload where you can afford to wait hours, not seconds.
Claude enforces rate limits at two levels:
| Limit Type | What It Measures | Typical Tier 1 |
|---|---|---|
| Requests per minute (RPM) | Number of API calls | 50 RPM |
| Tokens per minute (TPM) | Total input + output tokens | 40,000 TPM |
| Tokens per day (TPD) | Daily token budget | 1,000,000 TPD |
When you hit a limit, the API returns 429 Too Many Requests with a retry-after header.
import time
def call_with_backoff(fn, max_retries=5):
for attempt in range(max_retries):
try:
return fn()
except anthropic.RateLimitError as e:
wait = 2 ** attempt # 1, 2, 4, 8, 16 seconds
print(f"Rate limited. Waiting {wait}s...")
time.sleep(wait)
raise Exception("Max retries exceeded")
Live demonstration: prompt caching savings and batch API usage.
cache_creation_input_tokenscache_read_input_tokensresponse.usage object for each call. The cache hit/miss fields make the savings concrete and visible.