Qué es el caché web: la petición más rápida es la que nunca haces
El caché web guarda una copia de un archivo más cerca del usuario — en su propio navegador, o en el servidor de borde de una CDN — para que una petición repetida se sirva al instante en vez de hacer el viaje completo de ida y vuelta a tu origen, que cuesta de 100 a 300 milisegundos solo para conectar y recibir el primer byte. La petición más rápida es la que el navegador nunca tiene que hacer. Toda la disciplina se reduce a una pregunta: ¿cambia la URL cuando cambia el contenido? Si cambia — un archivo con hash como app.a1b2c3d4.js — lo cacheas por un año con immutable y el navegador no vuelve a preguntar por él. Si no cambia — una página HTML — la sirves con no-cache para que el navegador revalide y reciba un diminuto 304 Not Modified cuando nada se movió. Añade s-maxage para ajustar la CDN por separado, stale-while-revalidate para actualizaciones que nunca hacen esperar al usuario, y nombres de archivo con hash para que un despliegue nuevo invalide el caché de forma automática. Acierta con esa división y las visitas repetidas y los picos de tráfico se vuelven casi gratis — y un sitio estático, que es casi solo archivos cacheables e inmutables, obtiene todo el beneficio por defecto.
¿Qué pasa en realidad cuando un navegador cachea un archivo?
El caché guarda copias de recursos —páginas, imágenes, scripts— más cerca del usuario, ya sea en su navegador o en un caché intermedio como un proxy o una CDN, para que una copia en caché se sirva sin golpear el servidor de origen (DebugBear, 2026). El resultado son respuestas más rápidas y menos carga del servidor, porque el trabajo de traer, y muchas veces de generar, el recurso simplemente no vuelve a ocurrir.
El tamaño de la victoria es fácil de subestimar. Como lo pone una guía, la petición más eficiente es la que no se hace, y un acierto de caché en memoria en el navegador es prácticamente instantáneo frente a los 100 a 300 milisegundos que esperarías de otro modo solo para completar un handshake y ver el primer byte (Jono Alderson, 2026; DebugBear, 2026). Ese viaje de ida y vuelta ahorrado es tiempo que un visitante que vuelve nunca pasa mirando una pantalla en blanco, y por eso el caché está justo aguas arriba de las métricas de carga de nuestro pilar sobre Core Web Vitals y velocidad web.
La única pregunta que decide toda tu estrategia
Toda buena decisión de caché se reduce a una sola pregunta: ¿cambia la URL cuando cambia el contenido? Si cambia — porque el nombre del archivo lleva un hash de contenido — puedes cachear de forma agresiva con un max-age largo e immutable. Si no cambia — un documento HTML o una respuesta de API servida desde una URL estable — usas ventanas más cortas, revalidación, y stale-while-revalidate para equilibrar frescura y velocidad (Benedikt Sperl, 2026).
Ese encuadre evita los dos fallos que dominan los sitios reales: cachear un recurso cambiante tan fuerte que los usuarios quedan atrapados en una versión obsoleta, o no cachear nada porque los valores por defecto se sintieron más seguros (Benedikt Sperl, 2026). Responde primero la pregunta de la URL, y las directivas específicas de abajo casi se eligen solas.
Las directivas de Cache-Control que importan
Cache-Control es la cabecera principal para el caché, tras reemplazar a la más vieja Expires, y toma directivas separadas por comas (DebugBear, 2026). Las de frescura van primero: max-age=segundos fija cuánto tiempo una respuesta se mantiene fresca en navegadores y cachés compartidos, mientras que s-maxage aplica solo a cachés compartidos como las CDN y anula a max-age allí — dejándote mantener una ventana corta en el navegador y una más larga en la CDN, una directiva que muchos desarrolladores no saben que existe (Jono Alderson, 2026).
El resto fija las reglas de almacenamiento. public deja que cualquier caché guarde la respuesta y private la restringe al propio navegador del usuario; no-cache significa guárdala pero revalida antes de cada uso, mientras que no-store significa no la caches en absoluto — las dos son opuestas, no sinónimos (DebugBear, 2026). immutable le dice al navegador que el archivo nunca cambiará así que no debe revalidar ni al recargar, y stale-while-revalidate — la directiva más desaprovechada de la caja de herramientas — deja que un caché sirva una respuesta un poco obsoleta al instante mientras trae una fresca en segundo plano, para que el usuario nunca espere al origen (DigitalApplied, 2026).
Las dos recetas que más usarás
Para activos estáticos versionados —CSS, JavaScript y fuentes cuyos nombres incluyen un hash de contenido— la receta es Cache-Control: public, max-age=31536000, immutable, cacheándolos por un año sin revalidación (Benedikt Sperl, 2026). Esto es seguro justo porque el hash garantiza que la URL cambia siempre que el contenido lo hace, que es exactamente por qué los frameworks aplican esta cabecera a todo lo que está bajo sus directorios de activos con hash (DigitalApplied, 2026).
Para documentos HTML, haz lo contrario: usa no-cache (o el equivalente max-age=0, must-revalidate) para que el navegador siempre consulte con el servidor, recoja las nuevas URLs de activos con hash tras un despliegue, y aun así se beneficie de un 304 Not Modified rápido cuando la página no cambió (Benedikt Sperl, 2026). Esas dos recetas —cachea los activos para siempre, revalida el HTML cada vez— cubren la gran mayoría de un sitio normal.
Cómo funciona el cache-busting
El caché largo crea un problema obvio: si un archivo se cachea por un año, ¿cómo obtiene alguien una actualización? La respuesta es el hashing basado en contenido — incluir un hash del contenido del archivo en su nombre, así app.js se vuelve app.a1b2c3d4.js (Benedikt Sperl, 2026). Cuando el contenido cambia, el hash cambia, el nombre cambia, y el navegador lo trata como un recurso completamente nuevo que descargar, mientras la vieja copia en caché simplemente deja de estar referenciada.
Las herramientas de build modernas como Vite, Webpack y Rollup generan estos nombres con hash de forma automática, así que el cache-busting suele ser un valor por defecto en vez de una tarea (getpagespeed, 2026). Dos notas prácticas: prefiere un hash en el nombre a una cadena de consulta como ?v=123, porque algunas CDN ignoran las cadenas de consulta, y evita empaquetar todo tu sitio en un solo archivo, ya que un solo cambio invalida entonces el paquete entero para cada visitante que vuelve (getpagespeed, 2026; DebugBear, 2026).
Cómo revisa un navegador sin volver a descargar
Cuando un recurso está configurado para revalidar, el navegador no lo vuelve a descargar a ciegas — pregunta si algo cambió, usando validadores. Un ETag es una huella de la respuesta y Last-Modified es su marca de tiempo; el navegador los reenvía como If-None-Match e If-Modified-Since, y si nada cambió el servidor responde 304 Not Modified sin cuerpo alguno (oneuptime, 2026). Ese intercambio es por qué no-cache no es lento: una página HTML sin cambios cuesta un diminuto viaje de cabeceras en vez de una descarga completa, que es todo el punto de la revalidación.
Navegador y CDN: dos cachés, un set de reglas
El caché ocurre en al menos dos capas que leen las mismas cabeceras pero están en lugares distintos: el caché del navegador en el dispositivo del usuario, y el caché de la CDN en servidores de borde distribuidos (RequestMetrics, 2026). Una CDN sin una estrategia de caché real es solo un proxy caro — la diferencia entre una bien ajustada y una descuidada puede ser respuestas de 50 milisegundos frente a 500, y un origen que va sobrado frente a uno que se satura (oneuptime, 2026). Aquí es donde s-maxage y la purga por etiquetas se ganan su lugar, dejándote cachear el HTML en el borde por mucho tiempo y purgarlo en el instante en que se publica o edita, algo que cubrimos más en nuestra guía sobre qué es una CDN.
Una sutileza hace tropezar hasta a equipos con experiencia: max-age mide el tiempo transcurrido desde que la respuesta se generó en el origen, no desde que una CDN la recibió, y la cabecera Age descuenta ese tiempo de tránsito — así que una respuesta con max-age=600 que pasó dos minutos llegando al borde ya lleva dos minutos de vida al llegar (DigitalApplied, 2026). Verifica el comportamiento real con curl -I y la tasa de aciertos de tu CDN en vez de suponer que las cabeceras hacen lo que pretendías.
Los errores que sirven contenido obsoleto o filtrado
Unos pocos errores de caché son comunes y costosos. Poner immutable en una página HTML, o en cualquier recurso que pueda cambiar bajo la misma URL, encierra a los visitantes en contenido obsoleto por meses (Jono Alderson, 2026). Dejar entrar una respuesta autenticada a un caché compartido es peor — si una CDN cachea una página construida para un usuario con sesión, puede servirle los datos de una persona a otra, por lo que las rutas privadas deben devolver private, no-store (oneuptime, 2026).
La clase más sutil de error viene de cachés en capas que no se ponen de acuerdo. La mayoría de los problemas de contenido obsoleto se rastrean a dos capas que ambas creen que poseen el mismo valor, así que la disciplina es decidir, para cada pieza de dato, qué capa posee su frescura — los activos con hash pertenecen al navegador con un TTL de un año, los datos por usuario van detrás de private, no-store, y un valor de verdad en vivo no pertenece a ningún lado durable y debe servirse fresco (DigitalApplied, 2026). Y evita Vary: User-Agent, que multiplica las variantes guardadas y destroza tu tasa de aciertos (DigitalApplied, 2026).
Por qué un sitio estático es un sueño para el caché
Todo lo de arriba es más fácil cuando el sitio es estático, porque un sitio estático es casi solo archivos cacheables. Su HTML, su CSS y JavaScript con hash de contenido, y sus fuentes autoalojadas son todos seguros de cachear de forma agresiva en el borde, y no hay una consulta a base de datos por petición ni personalización por usuario que fuerce un no-store sobre lo importante. Las dos recetas cubren casi todo el sitio: activos con hash por un año con immutable, HTML revalidado en cada petición.
Esta es una ventaja estructural, no un truco de ajuste. Una herramienta de build como Astro pone un hash de contenido a los activos por defecto, así que la receta de caché agresivo de un año aplica de fábrica en vez de ser algo que un desarrollador tenga que construir y mantener (DigitalApplied, 2026). Se acumula con el resto del stack: las fuentes autoalojadas que cacheas para siempre, los scripts de terceros que nunca cargaste, y la CDN que lo sirve todo desde el borde son la misma decisión vista desde ángulos distintos — construye el sitio para que la petición más rápida, la que nunca se hace, sea el caso común y no la excepción.
Frequently asked
- ¿Qué es el caché web en términos simples?
- El caché web guarda una copia de un archivo —una página HTML, una imagen, un script— en algún lugar más cercano al usuario que tu servidor de origen, ya sea en el propio navegador del usuario o en un caché compartido como una CDN. Cuando el archivo se pide de nuevo, la copia en caché se sirve sin contactar al origen, lo que lo hace más rápido y reduce la carga del servidor. El ahorro es real: un acierto de caché en memoria es prácticamente instantáneo, frente a los 100 a 300 milisegundos que toma solo completar una conexión y recibir el primer byte de un servidor.
- ¿Cuál es la diferencia entre no-cache y no-store?
- Suenan parecido pero hacen cosas opuestas. no-cache significa que la respuesta se puede cachear, pero el navegador debe revalidarla con el servidor antes de usarla cada vez — así que igual obtienes una respuesta 304 Not Modified rápida cuando nada cambió. no-store significa no cachear la respuesta en absoluto, en ningún dispositivo ni intermediario; es para datos sensibles o por-usuario que nunca deben reutilizarse. Usa no-cache para el HTML que quieres mantener fresco; usa no-store solo para respuestas autenticadas o privadas.
- ¿Cuándo debería usar la directiva immutable?
- Solo en una URL cuyo contenido nunca cambiará — lo que en la práctica significa un archivo con un hash de contenido en su nombre, como app.a1b2c3d4.js. Para esos, Cache-Control: public, max-age=31536000, immutable cachea el archivo por un año y le dice al navegador que no revalide ni siquiera al recargar. Nunca pongas immutable en una página HTML ni en ningún recurso que pueda cambiar bajo la misma URL, porque encerrarás a los visitantes en una versión obsoleta por meses sin forma de empujar una actualización salvo cambiar la URL.
- ¿Cómo funciona el cache-busting?
- El cache-busting resuelve el problema de actualizar un archivo que le dijiste a los navegadores que cacheen por un año. La técnica es incluir un hash del contenido del archivo en su nombre, así app.js se vuelve app.a1b2c3d4.js. Cuando el contenido cambia, el hash cambia, el nombre cambia, y el navegador lo trata como un recurso completamente nuevo que debe descargar — mientras la vieja copia en caché simplemente se vuelve irrelevante. Las herramientas de build modernas como Vite y Webpack lo hacen de forma automática, y los hashes en el nombre son más fiables que las cadenas de consulta, que algunas CDN ignoran.
- ¿El caché ayuda si mi sitio es estático?
- Enormemente — un sitio estático es casi solo archivos cacheables. Su HTML, su CSS y JavaScript con hash, y sus fuentes autoalojadas son todos seguros de cachear de forma agresiva en el borde de una CDN, sin nada del trabajo de base de datos por petición ni la personalización por usuario que obliga a un sitio dinámico a desactivar el caché. Las herramientas de build como Astro ponen un hash de contenido a los activos por defecto, así que la receta de caché agresivo de un año con immutable aplica de fábrica en vez de ser algo que tengas que construir.