Guía de Caché HTTP: Acelera Tu Sitio Web Sin Infraestructura Adicional
Domina los encabezados Cache-Control, ETags, estrategias de caché en CDN y el comportamiento del caché del navegador para mejorar drásticamente el tiempo de carga de tu sitio y reducir los costos del servidor.
El caché es la optimización de rendimiento con mayor impacto que puedes implementar. Una respuesta en caché se sirve en microsegundos, no tiene costo alguno y no requiere ningún procesamiento del servidor. Sin embargo, la mayoría de las aplicaciones o bien cachean de forma demasiado agresiva (sirviendo contenido desactualizado) o no cachean en absoluto (desperdiciando ancho de banda y recursos de cómputo). Entender el caché HTTP lo transforma de una fuente de errores en una herramienta poderosa.
Cómo funciona el caché HTTP
Cuando un navegador o CDN recibe una respuesta, revisa los encabezados para decidir si almacenarla en caché y por cuánto tiempo. En la siguiente solicitud del mismo recurso, puede servir la copia en caché — sin contactar tu servidor en absoluto.
El ciclo de vida del caché tiene dos fases:
- Frescura — ¿Sigue siendo válida la copia en caché? Determinada por
Cache-Control: max-ageoExpires. - Validación — Si está desactualizada, ¿podemos confirmar con el servidor que el contenido no ha cambiado? Determinada por
ETagoLast-Modified.
Cache-Control: la directiva principal de caché
Cache-Control es el encabezado de caché más potente. Es una lista de directivas separadas por comas:
Cache-Control: public, max-age=31536000, immutable
Directivas clave
| Directiva | Significado |
|---|---|
public |
Cualquier caché (navegador, CDN, proxy) puede almacenarlo |
private |
Solo el navegador del usuario final puede cachear (no los CDN) |
no-cache |
Debe revalidarse con el servidor antes de cada uso (no significa "no cachear") |
no-store |
Nunca cachear — para datos sensibles |
max-age=N |
Cachear por N segundos |
s-maxage=N |
Tiempo máximo específico para CDN (reemplaza max-age en cachés compartidas) |
immutable |
El contenido nunca cambiará — omitir la revalidación por completo |
must-revalidate |
Cuando está desactualizado, debe revalidarse antes de servirse |
stale-while-revalidate=N |
Servir contenido desactualizado durante N segundos mientras se obtiene uno fresco en segundo plano |
⚠️
no-cacheNO significa "no cachear." Significa "guárdalo en caché, pero siempre verifica si sigue siendo válido." Usano-storesi realmente no quieres que algo se almacene en caché.
Estrategia de caché según el tipo de recurso
Cada tipo de recurso requiere una estrategia diferente:
Assets estáticos con hash de contenido (CSS, JS, imágenes)
Cache-Control: public, max-age=31536000, immutable
Si tu herramienta de compilación agrega un hash a los nombres de archivo (main.a3f9b2c.js), la URL cambia cuando el contenido cambia. Cachea indefinidamente — cualquier versión nueva obtiene una nueva URL.
Páginas HTML
Cache-Control: no-cache
O con un TTL corto:
Cache-Control: public, max-age=60, stale-while-revalidate=3600
El HTML cambia frecuentemente y enlaza a los assets con hash. Cachea brevemente o fuerza la revalidación.
Respuestas de API
# Datos públicos (p. ej., catálogo de productos)
Cache-Control: public, max-age=300, stale-while-revalidate=600
# Datos específicos del usuario
Cache-Control: private, max-age=60
# Datos en tiempo real (precios de acciones, marcadores en vivo)
Cache-Control: no-store
Datos sensibles (autenticación, pagos)
Cache-Control: no-store
Nunca cachear. Sin excepciones.
ETags y solicitudes condicionales
Cuando una respuesta en caché expira, el navegador no la descarta simplemente — le pregunta al servidor si sigue siendo válida. Esto es la revalidación.
ETags
Un ETag es una huella digital del contenido de la respuesta:
# El servidor envía:
ETag: "a3f9b2c8d4e1"
# La siguiente solicitud del navegador:
If-None-Match: "a3f9b2c8d4e1"
# Si no cambió, el servidor responde:
HTTP/1.1 304 Not Modified
(sin cuerpo — ahorra ancho de banda)
# Si cambió, el servidor responde:
HTTP/1.1 200 OK
ETag: "b7c2d4e9a1f3"
(respuesta completa nueva)
Una respuesta 304 Not Modified no tiene cuerpo — solo encabezados. Esto ahorra todo el ancho de banda que supondría volver a descargar el contenido.
Last-Modified
Similar, pero utiliza una marca de tiempo en lugar de un hash:
Last-Modified: Tue, 01 Apr 2026 10:00:00 GMT
# El navegador envía:
If-Modified-Since: Tue, 01 Apr 2026 10:00:00 GMT
Los ETags son más confiables (las marcas de tiempo pueden ser imprecisas en servidores con balanceo de carga).
Encabezado Vary: caché por variante de solicitud
El encabezado Vary le indica a los cachés qué encabezados de solicitud afectan la respuesta:
Vary: Accept-Encoding
Esto almacena una copia separada para las respuestas gzip y br. Usos comunes:
Vary: Accept-Encoding # Cachés separadas para comprimido/sin comprimir
Vary: Accept-Language # Cachés separadas por idioma
Vary: Accept # Cachés separadas para respuestas JSON vs HTML
⚠️
Vary: CookieoVary: Authorizationdesactiva efectivamente el caché en CDN — los CDN no pueden cachear respuestas específicas por usuario.
stale-while-revalidate: actualización en segundo plano
Uno de los patrones de caché modernos más útiles:
Cache-Control: max-age=60, stale-while-revalidate=600
- Servir instantáneamente desde caché durante los primeros 60 segundos (fresco)
- Para solicitudes entre 60 y 660 segundos: servir la copia desactualizada de inmediato, pero obtener una versión fresca en segundo plano
- Después de 660 segundos: debe revalidarse antes de servirse
Los usuarios siempre obtienen una respuesta rápida. El caché se mantiene actualizado sin obligar a nadie a esperar un viaje de ida y vuelta por la red.
Consideraciones sobre el caché en CDN
Los CDN (Cloudflare, CloudFront, Fastly) respetan los encabezados Cache-Control, pero añaden su propia capa de complejidad:
-
s-maxagete permite establecer diferentes TTL para el CDN y el navegador:Cache-Control: public, max-age=60, s-maxage=86400El navegador cachea durante 1 minuto; el CDN cachea durante 24 horas.
-
Purga de caché — cuando realizas un despliegue, purga el caché del CDN para los assets actualizados. La mayoría de los CDN ofrecen purga mediante API.
-
Claves de caché — los CDN cachean basándose en la URL + los encabezados Vary. Las cadenas de consulta generalmente se incluyen en la clave de caché.
Prueba del comportamiento del caché
Usa nuestro API Request Builder para inspeccionar los encabezados de respuesta y verificar que tu configuración de caché funciona correctamente:
- Realiza una solicitud y comprueba los encabezados
Cache-Control,ETagyLast-Modified - Realiza la misma solicitud nuevamente — verifica el encabezado
Age(segundos desde que se cacheó) yX-Cache: HIT - Comprueba
CF-Cache-Status(Cloudflare) oX-Cache(CloudFront) para confirmar el caché en CDN
En Chrome DevTools → pestaña Network → haz clic en un recurso → pestaña Headers — busca from disk cache o from memory cache en la respuesta.
Configuración de caché en Nginx
Configura los encabezados de caché a nivel de Nginx para un comportamiento consistente:
# Assets estáticos — cachear indefinidamente
location ~* \.(js|css|woff2|png|jpg|webp|svg)$ {
expires 1y;
add_header Cache-Control "public, immutable";
}
# HTML — revalidar siempre
location ~* \.html$ {
add_header Cache-Control "no-cache";
}
# API — caché corta con stale-while-revalidate
location /api/ {
add_header Cache-Control "public, max-age=60, stale-while-revalidate=600";
}
Usa nuestro Nginx Config Generator para generar una configuración de Nginx completa y optimizada para tu caso de uso.
Lista de verificación de caché
- Los assets estáticos (CSS/JS) usan nombres de archivo con hash de contenido +
max-age=31536000, immutable - El HTML se sirve con
no-cacheo unmax-agemuy corto - Las respuestas de API se cachean según la frecuencia de actualización
- Los datos sensibles usan
no-store - ETags o
Last-Modifiedhabilitados para solicitudes condicionales -
stale-while-revalidateen los endpoints de API apropiados - Encabezados de caché del CDN verificados y probados
Un caché HTTP correctamente configurado hace que tu sitio se sienta instantáneo para los visitantes recurrentes, reduce tus costos de ancho de banda y disminuye la carga del servidor — todo sin ninguna infraestructura adicional.