CDN
Servidores perto do usuário para entregar arquivos e respostas sem chegar à sua aplicação.
O problema: a distância até a origem
O servidor da aplicação fica numa região, digamos São Paulo. Um usuário em Lisboa está a cerca de 200 ms de ida e volta. Cada página carrega dezenas de arquivos (scripts, estilos, imagens) e algumas respostas de API. Mesmo com tudo rápido no servidor, a distância soma centenas de milissegundos. E um pico de acessos, como um lançamento ou uma campanha, cai inteiro sobre a origem.
Uma CDN (content delivery network) é uma rede de servidores, as bordas, espalhados por dezenas ou centenas de cidades. O usuário fala com a borda mais próxima. Se ela tem uma cópia válida da resposta, entrega na hora; se não tem, busca na origem, entrega e guarda a cópia para os próximos. Cloudflare, CloudFront, Fastly e Akamai são exemplos.
Medindo uma borda
Para medir sem uma CDN de verdade, colocamos um Nginx com cache na frente de uma origem, com 40 ms de atraso de rede em cada sentido entre os dois, simulando uma origem distante:
| Pedido | Tempo |
|---|---|
| Direto na origem | 85 ms |
Pela borda, primeira vez (busca na origem: MISS) | 130 ms |
Pela borda, depois (cópia guardada: HIT) | 3 a 6 ms |
A primeira requisição pagou a ida até a origem, e um pouco mais; as seguintes saíram da borda em poucos milissegundos, sem chegar à aplicação. Numa CDN real, a diferença é a mesma em escala maior: a origem fica num continente, e a borda, na cidade do usuário.
Quem decide o que é guardado: os cabeçalhos
A CDN não sabe se uma resposta pode ser compartilhada. Quem diz é a origem, pelos cabeçalhos HTTP, principalmente o Cache-Control:
| Diretiva | Significado |
|---|---|
public | Qualquer cache pode guardar, inclusive os compartilhados (CDN, proxy) |
private | Só o navegador do usuário pode guardar |
no-store | Ninguém guarda |
no-cache | Pode guardar, mas precisa confirmar com a origem antes de usar |
max-age=60 | Vale por 60 segundos (para todos os caches) |
s-maxage=300 | Vale por 300 segundos nos caches compartilhados; tem prioridade sobre max-age neles |
stale-while-revalidate=60 | Depois de vencer, pode servir a cópia velha por mais 60 s enquanto busca a nova |
stale-if-error=86400 | Se a origem falhar, pode servir a cópia velha por até um dia |
immutable | O conteúdo nunca muda nesse endereço; o navegador nem revalida |
E o ETag: uma etiqueta da versão da resposta. Quando a cópia vence, o cache pergunta à origem "ainda é a versão e5f7...?" (If-None-Match); se for, a origem responde 304 Not Modified, sem corpo, e a cópia ganha mais um prazo.
Três erros que desligam o cache
O teste mediu três situações comuns em que a borda não guarda nada, ou guarda mal:
| Situação | Resultado em três ou cinco pedidos |
|---|---|
A resposta tem Cache-Control: public, s-maxage=60 e um Set-Cookie | MISS, MISS, MISS |
A mesma página, com ?utm_source=a, b, c, d, e | MISS nos cinco |
| A mesma página, sem nada disso | MISS e depois HIT |
O Set-Cookie é o mais traiçoeiro: muitos frameworks iniciam uma sessão e acrescentam um cookie em toda resposta, inclusive nas páginas públicas. O Nginx, como a maioria das CDNs, não guarda respostas que criam cookies, porque o cookie é de um usuário. O cache existe, está configurado, e nunca acerta.
Os parâmetros de rastreamento (utm_source, fbclid, gclid) mudam a URL sem mudar o conteúdo. Cada variação vira uma entrada separada, e uma campanha com milhares de links diferentes nunca acerta o cache. As CDNs permitem tirar esses parâmetros da chave do cache.
O erro que vaza dados
O contrário é pior: guardar o que não podia ser guardado. A rota /minha-conta devolve os dados de quem pediu. Com Cache-Control: public, s-maxage=60:
| Pedido | Resposta |
|---|---|
| Ana pede a conta | conta de ana |
| Bruno pede a conta, logo depois | conta de ana |
A borda guardou a resposta da Ana e a entregou ao Bruno. Com Cache-Control: private, no-store, cada um recebeu a própria conta. Esse tipo de incidente já aconteceu em empresas grandes, quase sempre depois de uma mudança na configuração do cache ou de um cabeçalho padrão aplicado a todas as rotas.
A borda como proteção
Com a cópia guardada, a origem pode até cair. O teste guardou uma resposta com s-maxage=1 e stale-if-error=600, esperou a cópia vencer e desligou a origem:
| Rota | Com a origem fora do ar |
|---|---|
| A que estava no cache, vencida | HTTP 200, a cópia antiga (X-Cache: STALE) |
A que nunca foi guardada (tinha Set-Cookie) | HTTP 502 |
As páginas públicas continuaram no ar com o último conteúdo conhecido; só o que dependia da origem a cada pedido caiu.
Por que isso importa quando a IA escreve o código
Um assistente que configura uma CDN, ou que escreve as rotas atrás dela, costuma errar os cabeçalhos:
- Nenhum
Cache-Control, deixando cada CDN decidir sozinha. publicaplicado a todas as rotas por um middleware, inclusive as que têm dados do usuário.- Sessões e cookies criados em páginas públicas, que nunca entram no cache.
- Parâmetros de rastreamento na chave do cache.
- Arquivos estáticos sem nome versionado, com cache curto ou com dependência de limpeza manual.
- Nenhum
stale-if-error, e a CDN para de responder junto com a origem.
O próximo nível compara o que colocar na CDN, as estratégias de invalidação e as configurações da borda.
Prompts para aprofundar
Ao abrir no ChatGPT ou no Claude, o prompt é enviado ao serviço escolhido pela URL e também fica copiado na sua área de transferência.
CDN em cinco minutos
Explique em no máximo cinco minutos de leitura o que é uma CDN, para alguém que já publicou um site, mas sempre servido direto do próprio servidor. Cubra só o essencial: bordas e origem, acerto e falha de cache, o cabeçalho Cache-Control, por que um Set-Cookie desliga o cache e o risco de guardar dados de um usuário. Use o exemplo de uma loja online com usuários em vários países. No final, me faça três perguntas curtas para eu verificar se entendi, e corrija as minhas respostas.
Cache-Control por dentro
Quero entender o cabeçalho Cache-Control e a revalidação. Aja como um mentor e vá por etapas, esperando a minha resposta em cada uma: 1. public, private, no-store e no-cache, e a diferença entre os dois últimos. 2. max-age e s-maxage, e quem obedece a cada um. 3. stale-while-revalidate e stale-if-error. 4. ETag, If-None-Match e a resposta 304. 5. immutable e arquivos com nome versionado. Em cada etapa, me mostre uma resposta HTTP e peça que eu diga o que o navegador e a CDN fazem com ela.
Por que o cache não acerta
Quero entender os motivos pelos quais uma CDN configurada não guarda nada. Explique, com um exemplo de cada: 1. Set-Cookie em respostas públicas. 2. Parâmetros de rastreamento e a chave do cache. 3. Vary com Cookie ou User-Agent. 4. Cache-Control ausente ou com no-cache. 5. Respostas com Authorization ou cookies no pedido. Para cada um, diga como confirmar o problema com os cabeçalhos da resposta e como corrigir.
Incidentes de cache com dados pessoais
Quero entender como uma CDN pode entregar os dados de um usuário a outro. Explique: 1. Como uma resposta com dados pessoais acaba num cache compartilhado. 2. Os caminhos mais comuns: middleware que aplica public a tudo, regra da CDN que ignora a origem, mudança de configuração. 3. Por que a chave do cache sem o usuário faz todos receberem a mesma cópia. 4. As defesas na aplicação e na CDN. 5. Como testar automaticamente que rotas autenticadas nunca são guardadas. Depois me mostre três configurações e pergunte qual delas vaza dados.