HTTPQUERY
Español

Cache-Control

Uso

Los servidores de origen, los intermediarios y los clientes se apoyan en Cache-Control para ponerse de acuerdo sobre cuándo una respuesta almacenada sigue siendo utilizable y cuándo hace falta una copia nueva. Una misma respuesta suele combinar varias directivas para expresar una política de caché completa: cuánto tiempo almacenar, quién tiene permitido almacenar y qué hacer una vez que expira la frescura.

La siguiente tabla muestra qué directivas se aplican a las solicitudes, a las respuestas o a ambas.

Varias directivas se separan con comas dentro de un único valor de cabecera, o bien se reparten entre varias cabeceras Cache-Control. Cuando aparecen directivas contradictorias, se aplica la combinación más restrictiva.

Nota

Las cachés ignoran las directivas que no reconocen. Esto permite introducir directivas nuevas sin romper las implementaciones más antiguas.

Nota

Cuando no hay cabecera Cache-Control, las cachés aplican una frescura heurística. Una heurística habitual es el 10 % del tiempo transcurrido desde Last-Modified. Esto significa que los navegadores y las CDN sí almacenan en caché las respuestas sin Cache-Control. Definir Cache-Control de forma explícita evita comportamientos de caché inesperados.

Nota

Cache-Control determina cuándo revalidar (el tiempo de vida de la frescura). ETag determina cómo revalidar (la identidad del contenido). Ambos funcionan en conjunto: Cache-Control decide si hace falta revalidar y ETag decide si el contenido ha cambiado. La cabecera Pragma es el equivalente en HTTP/1.0 de Cache-Control: no-cache y está en la práctica obsoleta.

max-age

La directiva max-age indica a las cachés que devuelvan una respuesta almacenada solo si esta no tiene más antigüedad que el número de segundos indicado. Los valores no válidos, como los números negativos, se tratan como 0.

Cache-Control: max-age=<seconds>

Definir max-age=0 fuerza una revalidación de extremo a extremo. Este patrón tiene su origen en las implementaciones de HTTP/1.0 que carecían de soporte para no-cache.

max-stale

La directiva max-stale señala que se acepta una respuesta cuyo Age ha superado el tiempo de vida de la frescura en hasta el número de segundos indicado. La ventana de tolerancia empieza una vez que expira max-age.

Cache-Control: max-stale=<seconds>

Esta directiva resulta útil cuando el servidor de origen está temporalmente inaccesible y se acepta una respuesta ligeramente obsoleta.

min-fresh

La directiva min-fresh solicita una respuesta almacenada cuyo tiempo de vida de frescura restante sea de al menos el número de segundos indicado. La caché devuelve la copia almacenada solo si la respuesta seguirá fresca durante ese periodo adicional.

Cache-Control: min-fresh=<seconds>

no-cache

Una solicitud que lleva no-cache exige que la caché valide la respuesta almacenada con el origen antes de entregar la copia. Esto fuerza la revalidación sin descartar la entrada almacenada.

Cache-Control: no-cache

Nota

Para impedir por completo que una caché almacene una respuesta, utilice no-store en su lugar.

no-store

La directiva no-store pide a las cachés que no almacenen la solicitud ni la respuesta correspondiente.

Cache-Control: no-store

no-transform

La directiva no-transform prohíbe a los intermediarios modificar el cuerpo de la respuesta, por ejemplo recomprimiendo imágenes o convirtiendo formatos multimedia. La restricción se aplica tanto si el intermediario es un proxy de caché como si es una pasarela de reenvío.

Cache-Control: no-transform

only-if-cached

La directiva only-if-cached indica a la caché que devuelva una respuesta almacenada sin contactar con el origen. Si no existe ninguna respuesta almacenada adecuada, la caché devuelve un estado 504.

Cache-Control: only-if-cached

max-age

La directiva max-age declara el número de segundos durante los cuales la respuesta permanece fresca tras su generación. El contador arranca en el momento en que el origen crea la respuesta, de modo que el tiempo de tránsito y el tiempo pasado en cachés intermedias se descuentan de ese presupuesto.

Cache-Control: max-age=<seconds>

Una respuesta con max-age=3600 se mantiene fresca durante una hora. Transcurrida esa hora, las cachés consideran obsoleta la respuesta y, según las demás directivas presentes, la revalidan u obtienen una copia nueva.

s-maxage

La directiva s-maxage (max-age compartido) anula max-age en las cachés compartidas, como las CDN y los servidores proxy. Las cachés privadas de los navegadores ignoran s-maxage y recurren a max-age.

Cache-Control: s-maxage=<seconds>

no-cache

La directiva no-cache en la respuesta exige que las cachés revaliden la respuesta almacenada con el origen antes de cada reutilización. La caché sigue almacenando la respuesta, lo que permite solicitudes condicionales con ETag o Last-Modified.

Cache-Control: no-cache

Cuando no-cache incluye una lista de nombres de campo, solo esas cabeceras concretas requieren revalidación. El resto de la respuesta almacenada se entrega sin contactar con el origen.

Cache-Control: no-cache="Set-Cookie"

Nota

Para impedir el almacenamiento por completo, utilice no-store.

no-store

La directiva no-store impide que cualquier caché almacene la respuesta. Todas las solicitudes posteriores van al origen.

Cache-Control: no-store

Nota

no-cache permite el almacenamiento, pero exige revalidar antes de cada uso. La caché comprueba con el origen mediante If-None-Match o If-Modified-Since y recibe un 304 si el contenido no ha cambiado. no-store impide el almacenamiento por completo, de modo que no se conserva ninguna copia y cada solicitud obtiene la respuesta completa. Un error habitual es usar no-cache cuando lo que se pretende es no-store para datos sensibles, como registros bancarios o médicos. no-cache es eficiente para contenido que se actualiza con frecuencia. no-store es para contenido que nunca debe quedar en disco.

no-transform

La directiva no-transform en la respuesta impide que los intermediarios alteren el cuerpo de la respuesta antes de reenviarla, almacenen o no el contenido en caché.

Cache-Control: no-transform

must-revalidate

La directiva must-revalidate permite a las cachés entregar la respuesta mientras esta siga fresca. Una vez obsoleta, la caché contacta con el origen para revalidarla antes de volver a entregarla. Si el origen está inaccesible, la caché devuelve un 504 en lugar de entregar contenido obsoleto.

Cache-Control: must-revalidate

proxy-revalidate

La directiva proxy-revalidate funciona exactamente igual que must-revalidate, salvo que el requisito se aplica únicamente a las cachés compartidas. Las cachés privadas de los navegadores no se ven afectadas.

Cache-Control: proxy-revalidate

must-understand

La directiva must-understand indica a una caché que almacene la respuesta solo cuando reconozca el código de estado y comprenda los requisitos de caché asociados.

Cache-Control: must-understand, no-store

Combinar must-understand con no-store proporciona una alternativa de respaldo: las cachés que no admiten must-understand ignoran la directiva desconocida y respetan no-store en su lugar.

private

La directiva private restringe el almacenamiento a las cachés privadas, normalmente el navegador del usuario final. Las cachés compartidas, como las CDN y los servidores proxy, descartan la respuesta.

Cache-Control: private

public

La directiva public marca una respuesta como apta para su almacenamiento en cachés compartidas. Las respuestas que llevan una cabecera Authorization no se almacenan en cachés compartidas salvo que esté presente la directiva public.

Cache-Control: public

Nota

La directiva public es innecesaria cuando ya están presentes must-revalidate o s-maxage.

immutable

La directiva immutable garantiza que el cuerpo de la respuesta no cambiará durante el tiempo de vida de la frescura. Las cachés omiten las solicitudes condicionales para los recursos inmutables, lo que elimina los viajes de ida y vuelta de revalidación para recursos como los paquetes de JavaScript versionados o las imágenes con huella digital.

Cache-Control: public, max-age=31536000, immutable

stale-while-revalidate

La directiva stale-while-revalidate amplía la ventana de uso de una respuesta obsoleta. Una vez expirada la frescura, las cachés entregan la copia obsoleta mientras revalidan en segundo plano. El parámetro define durante cuántos segundos adicionales sigue siendo aceptable la respuesta obsoleta.

Cache-Control: max-age=600, stale-while-revalidate=30

Cuando termina la revalidación en segundo plano, la caché sustituye la entrada obsoleta por la respuesta nueva. Este patrón oculta a los usuarios finales la latencia de la revalidación.

stale-if-error

La directiva stale-if-error permite a las cachés entregar una respuesta obsoleta cuando el origen devuelve un estado de error (500, 502, 503 o 504) o está inaccesible. El parámetro fija el número de segundos, más allá del tiempo de vida de la frescura, durante los cuales la respuesta obsoleta sigue siendo utilizable como alternativa de respaldo.

Cache-Control: max-age=600, stale-if-error=86400

Ejemplo

Un recurso estático servido con un tiempo de vida de frescura largo y la marca immutable. El navegador y cualquier caché compartida almacenan esta respuesta durante un año sin revalidarla.

Cache-Control: public, max-age=31536000, immutable

Una respuesta de API destinada únicamente al navegador que realiza la solicitud. La caché almacena la respuesta durante cinco minutos y la revalida antes de reutilizarla una vez obsoleta.

Cache-Control: private, max-age=300, must-revalidate

Una política orientada a la CDN que concede a la caché compartida una ventana de diez minutos, mientras que la caché del navegador recibe un minuto. Las respuestas obsoletas se entregan durante un máximo de 30 segundos mientras la CDN revalida en segundo plano.

Cache-Control: s-maxage=600, max-age=60, stale-while-revalidate=30

Googlebot y max-age

La infraestructura de rastreo de Google implementa un almacenamiento en caché HTTP heurístico. La directiva max-age ayuda a Googlebot a determinar la frecuencia de rerrastreo. Una página con un max-age largo se vuelve a obtener con menos frecuencia, mientras que no-cache indica cambios frecuentes de contenido y justifica un rastreo más frecuente. Para ciertos códigos de estado, las respuestas sin ninguna cabecera de caché son heurísticamente almacenables de forma predeterminada, por lo que los orígenes que quieran impedir el almacenamiento por completo deben enviar no-store de forma explícita. Bingbot envía Cache-Control: no-cache en sus solicitudes y se apoya en crawl-delay dentro de robots.txt y en IndexNow para regular el ritmo de rastreo.

Nota

Para obtener ayuda con SEO y almacenamiento en caché, póngase en contacto con los consultores SEO exempleados de Google de Search Brothers.

Diagnóstico

Los comportamientos de caché inesperados se deben a malentendidos sobre las directivas, a anulaciones de la CDN o a cabeceras contradictorias.

Se entrega contenido obsoleto pese a la directiva no-cache. La directiva no-cache no impide el almacenamiento. Las cachés almacenan la respuesta y la revalidan en cada reutilización. Para impedir el almacenamiento por completo, utilice no-store. Combine ambas cuando haya datos sensibles de por medio: Cache-Control: no-cache, no-store.

La CDN ignora las directivas de Cache-Control. Muchas CDN anulan el Cache-Control del origen con sus propias políticas. Cloudflare respeta de forma predeterminada las cabeceras del origen, pero las anula cuando hay una Page Rule o una Cache Rule activa. AWS CloudFront usa la cabecera del origen salvo que haya una política de caché con TTL personalizados asociada. Revise el panel de la CDN en busca de reglas de anulación antes de depurar la configuración del origen.

El contenido obsoleto persiste tras reducir max-age. Los nodos perimetrales de la CDN y las cachés de los navegadores conservan las respuestas hasta que expira el max-age original. Reducir el valor en el origen no purga las copias ya almacenadas en caché. Ejecute una purga en la CDN después de cambiar los tiempos de vida de la caché. En Cloudflare, purgue por URL o utilice una purga completa de la zona. En CloudFront, cree una invalidación para las rutas afectadas.

El navegador muestra la página antigua al navegar hacia atrás o adelante pese a no-store. La caché de navegación hacia atrás y adelante (bfcache) de Chrome, Firefox y Safari restaura el estado completo de la página desde la memoria, sorteando no-store. Este comportamiento es intencionado y no representa una violación de la caché. Inspeccione la cabecera Cache-Control en la pestaña Network de DevTools con “Disable cache” desmarcado para confirmar que la cabecera llega al navegador. Añadir escuchadores del evento unload desactiva la bfcache en algunos navegadores, pero degrada el rendimiento.

La cabecera Expires entra en conflicto con Cache-Control. Cuando ambas cabeceras están presentes, Cache-Control: max-age tiene prioridad sobre Expires. Elimine la cabecera Expires para evitar confusiones. En nginx:

expires off;
add_header Cache-Control "max-age=3600";

En Apache:

Header unset Expires
Header set Cache-Control "max-age=3600"

Diagnosticar las cabeceras de caché con curl y DevTools. Ejecute curl -I https://example.re para inspeccionar las cabeceras de respuesta procedentes del origen. Añada -H “Cache-Control: no-cache” para sortear las cachés de la CDN y llegar directamente al origen. En las DevTools del navegador, abra la pestaña Network, seleccione la solicitud y revise la sección Response Headers. Fíjese en las cabeceras Age, X-Cache y CF-Cache-Status para determinar si la respuesta provino de un nodo perimetral de la CDN o del origen.