Qué hace un CDN realmente con una petición

Un usuario en Tokio que carga una página alojada en un servidor de Virginia paga esa distancia dos veces: una vez para que la petición llegue, otra para que la respuesta vuelva. La fibra viaja a una fracción fija de la velocidad de la luz, y ese trayecto por sí solo cuesta entre 150 y 200ms de ida y vuelta antes de que el origen haya hecho ningún trabajo. Añade una consulta a la base de datos y algún salto lento de más, y una página que se siente instantánea a la vuelta de la esquina se siente lenta al otro lado del planeta.

Un CDN, o red de distribución de contenidos, arregla esto para el contenido que se puede copiar: imágenes, CSS, paquetes de JavaScript, segmentos de vídeo, a veces páginas HTML enteras. Una red de servidores colocados cerca de los usuarios guarda copias de ese contenido y responde directamente, así que la mayoría de las peticiones nunca cruza el océano. El origen sigue teniendo la versión autoritativa. El CDN se coloca delante e intercepta todas las peticiones que puede servir desde una copia.

Cómo se decide qué servidor responde a una petición

Un operador de CDN ejecuta servidores en muchas ubicaciones físicas, normalmente llamadas Points of Presence, o PoPs: centros de datos en las grandes ciudades o cerca de ellas, cada uno con una parte del contenido cacheado y un camino rápido de vuelta al origen para todo lo demás. Dos mecanismos deciden qué PoP atiende una petición concreta, y los CDN grandes usan ambos.

El enrutamiento basado en DNS resuelve el mismo hostname a IPs distintas según de dónde venga la consulta. Una consulta DNS para assets.example.com desde un resolver en Fráncfort recibe la IP de un PoP en Fráncfort; la misma consulta desde São Paulo recibe una IP completamente distinta.

Anycast va más allá. Muchos PoPs anuncian la misma IP por BGP, y el enrutamiento normal de internet decide a cuál llega realmente un paquete dado, según la topología de la red y no la geografía. El CDN nunca toma esa decisión. El failover también es más rápido: cuando un PoP se cae de la red, los routers dejan de enviarle tráfico, sin ningún cambio de DNS que propagar.

1
2
3
4
5
6
cliente (Tokio)  ---DNS/anycast--->  PoP más cercano  ---cache hit--->  respuesta
                                          |
                                    cache miss
                                          |
                                          v
                                   origen (Virginia)

De cualquier forma, el cliente nunca habla directamente con el origen para contenido cacheado. Habla con el PoP que la capa de enrutamiento eligió, y ese PoP o bien tiene el contenido o lo pide una vez y lo recuerda. Cada PoP hace el trabajo de un reverse proxy delante del origen: termina la conexión del cliente y decide qué pasa después, con una cache adjunta y miles de copias funcionando a la vez por todo el mundo.

Cache hit vs cache miss: cómo saber cuál tuviste

La primera petición de una URL a través de un PoP dado es un cache miss. El PoP no tiene nada guardado, así que pide al origen, guarda una copia según las reglas de la respuesta, y la devuelve. Cada petición posterior de esa URL, desde cualquier cliente enrutado al mismo PoP, es un hit: servida desde el almacenamiento del PoP, sin que el origen intervenga, hasta que la copia expira o se purga.

Un comando te dice cuál de los dos tuviste:

1
curl -I https://assets.example.com/app.css

Una respuesta cacheada lleva una cabecera propia del proveedor que nombra el resultado. Cloudflare añade CF-Cache-Status con valores como HIT, MISS, EXPIRED (el TTL se acabó, así que el PoP volvió a pedirlo), REVALIDATED (el origen confirmó que la copia antigua seguía siendo válida) o DYNAMIC (el CDN decidió que esta respuesta no es cacheable). El equivalente en Fastly es X-Cache: HIT o X-Cache: MISS. Ejecuta la misma petición dos veces sobre una URL cacheable y la segunda debería pasar de MISS a HIT.

1
2
3
4
5
HTTP/2 200
cache-control: public, max-age=3600
cf-cache-status: HIT
age: 412
content-type: text/css

age son los segundos que han pasado desde que el PoP obtuvo esta copia del origen. Aquí son 412 segundos de un TTL de 3600, así que a la copia le queda casi una hora antes de que la siguiente petición dispare una descarga nueva.

Cómo le dice Cache-Control al CDN qué cachear

El CDN no adivina qué cachear. El origen se lo dice mediante la cabecera Cache-Control en cada respuesta.

DirectivaQué hace
max-age=NCuánto tiempo puede guardar la respuesta cualquier cache (navegador o CDN), en segundos
s-maxage=NCuánto tiempo puede guardarla una cache compartida (el CDN); sobrescribe max-age solo para el CDN, los navegadores siguen usando max-age
publicPermite cachear incluso respuestas que de otro modo parecerían privadas (por ejemplo, con una cabecera Authorization)
privateSolo el navegador puede cachear esto; el CDN no debe hacerlo
no-cacheLas caches pueden guardarlo pero deben revalidar con el origen antes de servirlo de nuevo
no-storeNo cachear esto en ningún sitio, ni navegador ni CDN

Para un recurso estático con un nombre de archivo con hash (app.a3f9c1.css), lo habitual es una configuración agresiva: Cache-Control: public, max-age=31536000, immutable. El nombre del archivo cambia cada vez que cambia el contenido, así que un año es seguro. Una copia obsoleta de app.a3f9c1.css es una contradicción, porque ese nombre exacto solo apunta a una versión del archivo.

Para HTML o una respuesta de API que quieres cachear pero más fresca, Cache-Control: public, s-maxage=60, max-age=0 la mantiene en el CDN durante un minuto mientras los navegadores revalidan cada vez. Es el mismo instinto de TTL corto y cache-aside detrás de cómo funciona el caching con Redis, aplicado con una cabecera HTTP en lugar de código de aplicación.

Haz esto mal en el otro sentido y filtras datos. Servir una página por usuario con Cache-Control: public, max-age=3600 y sin Vary en la cookie de sesión significa que el CDN puede entregarle la página cacheada del usuario A al usuario B.

Cómo purgar una cache de CDN obsoleta

A veces un TTL no basta: has desplegado un arreglo y no puedes esperar una hora a que llegue a todos. Todos los CDN exponen una API de purga o una acción desde el panel para esto. Le dices que una URL, o toda una zona, ya no es válida, y la siguiente petición se trata como un cache miss sin importar cuánto TTL le quedara.

La estrategia más barata es no tener que purgar nunca. Versiona el nombre del archivo con un hash del contenido o un parámetro de query, así cada despliegue es una URL nueva con su propia entrada de cache, y la copia obsoleta de la URL vieja deja de pedirse por completo. Reserva la purga para lo que no puedes evitar: un incidente, una retirada legal, una cache envenenada por una cabecera Vary mal configurada.

Cuándo un CDN no ayuda, y qué te cuesta

Las respuestas personalizadas no son cacheables de ninguna forma útil. Un dashboard con sesión iniciada, una página de carrito, cualquier cosa ligada a una sesión: la siguiente petición seguro que quiere contenido distinto. Poner un CDN delante de esos endpoints no consigue nada salvo una falsa sensación de haber añadido caching, y si las reglas de cache están mal, arriesga servir la respuesta privada de un usuario a otro.

Un CDN también añade una capa más que depurar. “Funciona en local pero no en producción” a veces significa que el código está bien y un PoP está sirviendo una respuesta cacheada de antes de tu arreglo; la petición no llega al origen hasta que el TTL se acaba o purgas la cache.

La forma del tráfico también importa. Una herramienta interna, o un servicio regional sin audiencia internacional, paga por PoPs que nunca usa y recupera latencia que nunca tuvo. Un CDN resuelve dos problemas concretos: el trayecto hasta usuarios lejanos, y la carga repetida sobre el origen. Si ninguno de los dos es el tuyo, es infraestructura sin nada que hacer.

Cómo comprobar si ya tienes un CDN

Ejecuta curl -I contra un recurso estático de un sitio que mantengas. Si la respuesta lleva cache-control, una cabecera age, o un estado propio de un proveedor como CF-Cache-Status o X-Cache, algo ya está cacheando delante de tu origen, lo hayas configurado tú a propósito o venga incluido con tu hosting. Si esas cabeceras faltan en recursos que se piden desde más de una región, ese es el caso concreto para añadir uno: Cloudflare, AWS CloudFront y Fastly ponen un dominio detrás de un CDN en un plan gratuito o de pago por uso en menos de una hora, y el código del origen no tiene que cambiar.

Artículos relacionados