Caché de prompts en Ollama — dónde editas decide la factura
Seis sondas, una VM nueva: una repetición exacta reevaluó 1,539 tokens en 0.2 s frente a 75.6 s en frío — y una palabra movida a mitad del prompt facturó 49 s.
verify: seis sondas, una VM nueva, seed 42 · temp 0 · ollama 0.40.16 · recibos abajo, log promptcache-2026-11-12.log
Fig 1 — seis sondas, un prompt. Las barras atenuadas son el recibo: una edición a mitad del prompt devolvió el 65% de la factura en frío, y reordenar cobró más que la propia carga en frío.
¿Qué guarda realmente la caché de prompts de ollama?
No tu texto. Cuando ollama evalúa un prompt calcula un tensor KV por cada token — la huella de atención de ese token frente a todos los anteriores — y el runner conserva esos tensores en RAM mientras el modelo siga cargado. Un prompt nuevo se coteja con ese almacén token por token, desde el frente. Cada token que continúa exactamente el prefijo viejo es gratis. El primer token que difiere es la frontera: todo desde ahí hasta el final se relee a precio completo. Es la misma residencia KV que cubrió nuestra pieza KV-cache para el timing de descarga — la caché que sirve velocidad es la caché que retiene RAM (y por eso keep_alive decide cuánto sobrevive cada cual — la pieza de la ventana de contexto tiene la parte del dimensionado de esa factura).
keep_alive si tu bucle habla con pausas.¿Por qué la repetición exacta costó 0.2 segundos?
La sonda: un prompt de 1,539 tokens — ocho secciones numeradas de hechos de logs de fixture, luego una pregunta — preguntado en frío sobre una VM nueva. El motor leyó los 1,539 tokens a 20.4 tok/s y facturó 75.6 s de evaluación de prompt. La pregunta idéntica, reenviada con el modelo aún residente: 0.2 s. Mismo endpoint, mismo cuerpo, nada conmutado — ollama hace esto sin flag, sin cache: true, sin conjuro de calentamiento. Llevas tiempo cobrando el descuento cada vez que re-preguntas; este post va de no devolverlo.
curl http://localhost:11434/api/generate -d '{
"model": "qwen3:4b",
"prompt": "<your 1,500-token prompt>",
"keep_alive": "45m",
"think": false,
"options": {"seed": 42, "temperature": 0, "num_predict": 128}
}'
verify: P1 frío 75.6 s → P2 repetición 0.2 s, cuerpo de sonda idéntico byte a byte, modelo residente · promptcache-2026-11-12.log
Dónde editas decide qué pagas
Conservamos el cuerpo de 1,539 tokens y movimos exactamente una palabra, de tres formas. Cambia una palabra en la última frase: 4.2 s — la cabeza compartida sobrevivió, solo la cola se releyó. Añade una frase después de la pregunta: 1.4 s — acierto casi total, cinco tokens nuevos facturados al margen. Cambia una palabra en el hecho 41 de 96, a mitad de cuerpo: 49.2 s — el 65% de la factura en frío, pagado por reubicar un adjetivo. La caché tiene memoria de elefante y perdón de aduanero: lo recuerda todo, y un solo formulario erróneo anula todos los sellos de la libreta — para todo lo que va detrás del formulario erróneo.
| sonda | qué cambió | prompt-eval | pregunta completa | vs frío |
|---|---|---|---|---|
| P1 frío | nada — VM nueva, primera pregunta | 75.6 s | 111.8 s | referencia |
| P2 repetición | nada — cuerpo idéntico | 0.2 s | 26.6 s | 370× más rápido |
| P3 sufijo | +1 frase después de la pregunta | 1.4 s | 27.2 s | 54× más rápido |
| P4 edición al medio | 1 palabra en el hecho 41/96 | 49.2 s | 75.2 s | 65% del frío |
| P5 reordenar | secciones 1–2 ↔ 7–8 intercambiadas | 79.9 s | 135.5 s | peor que en frío |
| P6 casi al final | 1 palabra en la última frase | 4.2 s | 34.0 s | 18× más rápido |
prompt de 1539 tokens · prompt-eval es la factura de relectura; la «pregunta completa» añade la generación de 128 tokens, que se mantuvo ~25–29 s todo el tiempo.
¿Por qué reordenar factura más que una carga en frío?
Porque la frontera está en el token ~1. Intercambia las dos primeras secciones por las dos últimas y el prefijo compartido queda vacío — el match muere de inmediato y cada token refactura. Pero P5 facturó 79.9 s, no 75.6 s: 5.7% por encima de la carga en frío por la que tiró el descuento. No vamos a fingir que atrapamos al culpable — la nota honesta es que la pasada de generación también corrió 2.1× más lenta en esa sonda (55.4 s contra 25.5–29.4 s de cada otra pregunta, mismo seed, mismo presupuesto). El estado caliente del servidor se suma a la factura de formas que un diagrama de caché no muestra; la pieza de determinismo ya se topó con este testigo con un token volcado a temp 0. Lo que sí podemos afirmar como recibo: un prompt reordenado no es un «mismo prompt, otro orden». Es una factura nueva de fábrica, más ruido.
La lista de correcciones
| síntoma | qué está pasando | la corrección |
|---|---|---|
| cada petición se siente como una carga en frío | el modelo se descarga entre preguntas — la caché muere con él | sube keep_alive; revisa load_duration en la respuesta |
| ediciones minúsculas del prompt, latencia enorme | la edición cae a mitad de prompt; la cola refactura desde la divergencia | mueve la parte volátil a la cola del prompt |
| la «misma petición» factura distinto en cada run | el orden o el boilerplate derivó entre peticiones | congela la cabeza byte a byte; haz diff de los prompts, no de las vibras |
P1 cold-full-ask prompt_eval 75,646 ms (1,539 tok · 20.4 tok/s) wall 111.8 s P2 exact-repeat prompt_eval 203 ms wall 26.6 s P3 suffix-only prompt_eval 1,402 ms (+5 tok) wall 27.2 s P4 mid-edit-kill prompt_eval 49,176 ms (1 word, fact 41/96) wall 75.2 s P5 reorder-full-miss prompt_eval 79,878 ms (secs 1–2 ↔ 7–8) wall 135.5 s P6 edit-near-end prompt_eval 4,189 ms (1 word, last sentence) wall 34.0 s
Un prompt. Seis facturas, de 0.2 a 79.9 segundos — un rango de 370× sin cambiar ningún ajuste ni conmutar ningún flag. La caché siempre estuvo encendida. La única variable fue dónde nos atrevimos a editar.
última prueba 2026-11-12
qwen3:4b · 2,497,293,931 B · sha256 359d7dd4…74e7 · ollama 0.40.16 · una VM Arch nueva, 2 vCPU — bench CPU, cero declaraciones VRAM