Bajé mi factura de Claude 90% con prompt caching
Anthropic permite cachear el system prompt por 1 hora. Si tu app hace múltiples llamadas con instrucciones grandes, el ahorro es brutal. Aquí está cómo lo configuré y los números reales.
Mi sistema de 11 agentes hace ~4,200 llamadas a Claude al mes. Cada agente tiene un system prompt de ~2-4K tokens (rol, herramientas, restricciones, ejemplos). Sin caching, cada llamada paga esos tokens completos.
Con prompt caching de 1 hora, pago el system prompt una vez y las siguientes N llamadas dentro de la hora pagan ~10% del costo de esos tokens.
Mi cache hit rate actual: 85%. Mi factura cayó de ~$50 USD/mes a $4-5 USD/mes. Aquí está cómo.
La feature
Anthropic permite marcar bloques de tu request como cacheables:
client.messages.create(
model="claude-sonnet-4-6",
max_tokens=2000,
system=[
{
"type": "text",
"text": SYSTEM_PROMPT, # tu instrucción grande
"cache_control": {"type": "ephemeral", "ttl": "1h"},
}
],
messages=[...]
)
cache_control.ttl: "1h" extiende el cache de 5 minutos (default) a 1 hora.
Cuánto cuesta el cache
| Operación | Costo (vs input normal) |
|---|---|
| Cache write (primera vez) | 125% del input (+25% de penalty) |
| Cache read (siguientes llamadas, mientras viva el cache) | 10% del input |
| Cache miss (después del TTL) | escribe de nuevo (125%) |
El break-even: si una sola conversación va a hacer 2 o más llamadas con el mismo system prompt dentro de 1 hora, ya estás ahorrando.
Cuándo NO usar cache
- Llamadas únicas, esporádicas, sin patrón → pagas el 25% extra y nunca lees del cache
- System prompt corto (<1K tokens) → el ahorro absoluto es despreciable
- System prompt que cambia entre llamadas → cada cambio invalida el cache
Cuándo SÍ es genial
- Chatbots con system prompt grande (mi caso)
- Procesamiento batch sobre un contexto fijo (ej: analizar 100 PRs con el mismo prompt base)
- Agentes con tool schemas grandes (los schemas son parte del system y pesan)
La medición — qué reportar
Anthropic devuelve en el response:
resp.usage.input_tokens # tokens nuevos (no cacheados)
resp.usage.cache_creation_input_tokens # tokens que se escribieron al cache
resp.usage.cache_read_input_tokens # tokens leídos del cache
resp.usage.output_tokens # respuesta
Mi tabla token_usage:
CREATE TABLE token_usage (
id SERIAL PRIMARY KEY,
agent_name TEXT NOT NULL,
model TEXT NOT NULL,
input_tokens INT NOT NULL DEFAULT 0,
output_tokens INT NOT NULL DEFAULT 0,
cache_creation_tokens INT NOT NULL DEFAULT 0,
cache_read_tokens INT NOT NULL DEFAULT 0,
created_at TIMESTAMPTZ DEFAULT NOW()
);
El cache hit rate se calcula:
SELECT
SUM(cache_read_tokens) AS reads,
SUM(input_tokens + cache_creation_tokens + cache_read_tokens) AS total_in,
ROUND(100.0 * SUM(cache_read_tokens) /
NULLIF(SUM(input_tokens + cache_creation_tokens + cache_read_tokens), 0), 1)
AS hit_rate_pct
FROM token_usage
WHERE created_at::date = CURRENT_DATE;
El número real, con cálculo correcto
Para Sonnet 4.6:
- Input normal: $3/1M tokens
- Cache read: $0.30/1M tokens (10%)
- Cache write: $3.75/1M tokens (125%)
Día típico mío:
- 140 llamadas
- 3,200 tokens de system por llamada (~450K tokens si todo fuera cache miss)
- 85% cache hit rate → solo 21 cache writes, 119 cache reads
Sin caching: 450K × $3/1M = $1.35/día Con caching: 21 × 3,200 × $3.75/1M + 119 × 3,200 × $0.30/1M = $0.25 + $0.11 = $0.36/día
Ahorro: 73% solo en input. Aplicado al mes: $40 → $11 solo por esto.
El truco para mantener el cache caliente
Si tu app tiene patrón de tráfico irregular (ej: ráfaga de 10 llamadas, después nada por 2h, después otra ráfaga), el cache muere entre ráfagas.
Mi trampita: un scheduled job que cada 50 minutos hace una llamada minimalista al modelo más usado, con el system prompt cacheado. El cache se renueva continuamente.
Costo del job: 1 llamada × 3,200 tokens read + ~20 tokens output ≈ $0.001/día. Lo que me ahorra en cache misses: mucho más.
Combina con model routing
Cache + model routing es donde está el verdadero ahorro. Mi router (que ya escribí en otro post) manda el 80% de llamadas a Haiku 4.5. Haiku ya es 10× más barato que Sonnet. Sumándole 85% cache hit rate, el costo por llamada simple es:
Haiku input normal: $0.80/1M
Haiku cache read: $0.08/1M (10%)
Una llamada simple ahora cuesta ~$0.0001 USD. Por eso mi factura completa es $5/mes con 11 agentes corriendo 24/7.
TL;DR para tu próximo proyecto
- Si tu system prompt es >1K tokens y haces más de 1 llamada por sesión: activa cache con TTL
1h. - Loggea
cache_creation_tokensycache_read_tokensdesde el día 1 — sin medición no sabes si está funcionando. - Combina con model routing — el ahorro se multiplica.
- Si tu tráfico es a ráfagas, considera un keep-alive job.
Los números de esta entrada vienen del bot que está atendiendo oficina.lalu.dev en este momento. Los stats del cache hit rate los puedes ver en vivo arriba a la derecha del sitio.