System Design

CDN — Content Delivery Network

Rede de servidores distribuídos geograficamente que entrega conteúdo aos usuários a partir do nó mais próximo, reduzindo latência e descarregando o servidor de origem — ao custo de lidar com invalidação de cache e consistência eventual na borda.

Intenção

Uma CDN distribui cópias do conteúdo em servidores espalhados pelo mundo para que cada usuário seja atendido pelo nó geograficamente mais próximo. Em vez de toda requisição atravessar oceanos até o servidor de origem, ela é respondida por um PoP (Point of Presence) local — reduzindo o tempo de ida e volta (RTT) de centenas de milissegundos para dezenas.

O benefício é duplo: latência menor para o usuário (o dado percorre menos distância física) e carga reduzida no servidor de origem (a maioria das requisições é absorvida pelos PoPs sem jamais chegar à origem). CDNs são a camada de cache mais externa de um sistema web e aparecem de forma praticamente obrigatória em qualquer produto com audiência geográfica distribuída.

Problema

A velocidade da luz impõe um limite físico na latência de rede: um pacote entre São Paulo e Frankfurt leva aproximadamente 100–120 ms só de RTT, mesmo em condições ideais. Em sistemas onde o servidor de origem fica em uma única região, usuários distantes pagam esse custo em toda requisição.

  • Latência geográfica: um usuário europeu acessando um servidor nos EUA paga 80–150 ms de RTT a cada recurso carregado. Uma página com 30 assets pode facilmente acumular segundos de latência de rede antes mesmo de qualquer processamento.
  • Sobrecarga da origem em picos: um lançamento de produto ou evento viral pode multiplicar por cem o tráfego em minutos. Sem absorção na borda, todo esse volume chega diretamente ao servidor de origem, que frequentemente não tem capacidade para o pico.
  • Custo de banda da origem: transferir gigabytes ou terabytes de vídeo, imagens e assets a partir de um único datacenter tem custo alto — tanto financeiro quanto em largura de banda. Distribuir esse tráfego pelos PoPs reduz o custo de saída da origem.
  • Disponibilidade e resiliência: um servidor de origem único é um ponto de falha. Se ele estiver indisponível, nenhum usuário consegue acessar o conteúdo — a menos que haja uma camada de borda servindo conteúdo cacheado durante a indisponibilidade.

Como funciona

PoP (Point of Presence)

Cada nó de uma CDN é chamado de PoP: um servidor (ou cluster de servidores) com armazenamento local instalado em um datacenter próximo a uma concentração de usuários. A CDN redireciona cada usuário para o PoP geograficamente mais próximo via DNS ou Anycast IP.

  Usuário (BR, São Paulo)
        │
        ▼
  ┌─────────────────┐
  │  CDN PoP SP     │  cache HIT?
  │  (São Paulo)    │──────────────► Resposta (baixa latência)
  └────────┬────────┘
           │ cache MISS
           ▼
  ┌─────────────────┐
  │  Servidor de    │
  │  Origem (EUA)   │──► popula cache no PoP ──► Resposta
  └─────────────────┘

  Usuário (EU, Frankfurt)
        │
        ▼
  ┌─────────────────┐
  │  CDN PoP FRA    │  cache HIT?
  │  (Frankfurt)    │──────────────► Resposta (baixa latência)
  └─────────────────┘

Cache HIT vs MISS

Quando um usuário requisita um recurso:

  • HIT: o PoP tem uma cópia válida em cache e a retorna diretamente, sem contatar a origem. Latência mínima — apenas a distância até o PoP.
  • MISS: o PoP não tem o recurso (ou o cache expirou). O PoP busca na origem, armazena a resposta localmente e a retorna ao usuário. A próxima requisição pelo mesmo recurso será um HIT.

A taxa de HIT (hit rate) é a métrica central de uma CDN: quanto maior, mais eficiente é a distribuição e menos tráfego chega à origem. Taxas abaixo de 80–90% para conteúdo estático geralmente indicam problemas na configuração de TTL ou na estratégia de cache.

Cache-Control e TTL

O servidor de origem define por quanto tempo o PoP pode armazenar e servir um recurso através do cabeçalho HTTP Cache-Control. O valor max-age especifica o TTL em segundos:

  # Asset estático com hash — TTL longo (1 ano)
  Cache-Control: public, max-age=31536000, immutable

  # HTML — TTL curto (sem cache ou curto, pois muda frequentemente)
  Cache-Control: no-cache

  # Resposta de API pública — TTL médio (5 minutos)
  Cache-Control: public, max-age=300, s-maxage=300

  # Resposta com dados privados — não deve ser cacheada na CDN
  Cache-Control: private, no-store

TTL longo significa menos chamadas à origem e maior hit rate, mas mais risco de servir conteúdo desatualizado. TTL curto garante dados frescos, mas reduz a eficiência do cache.

Invalidação de cache

Forçar o PoP a descartar o conteúdo cacheado antes do TTL expirar é chamado de invalidação. É necessário quando um deploy novo precisa ser servido imediatamente sem esperar o TTL.

O problema: a invalidação precisa ser propagada para todos os PoPs da rede, o que leva tempo (segundos a minutos) e tem custo — muitas CDNs cobram por operação de invalidação, e a propagação não é instantânea.

A estratégia mais robusta é o cache busting via URL: incluir um hash do conteúdo no nome do arquivo. Quando o arquivo muda, a URL muda, o cache é ignorado naturalmente (pois é uma URL nova) e o arquivo antigo expira pelo TTL normalmente.

  # Sem cache busting — problema ao fazer deploy
  /static/app.js           # mesma URL, PoP serve versão antiga

  # Com cache busting — deploy seguro
  /static/app.a3f9b2c1.js  # URL nova a cada build, PoP sempre busca
  /static/app.min.js?v=42  # alternativa: query string com versão

Tipos de conteúdo: estático vs dinâmico

  • Conteúdo estático (ideal para CDN): imagens, CSS, JavaScript, fontes, vídeos — não variam por usuário e mudam raramente. Taxas de HIT próximas de 100% são alcançáveis. O CDN foi originalmente criado para esse caso.
  • Conteúdo dinâmico (CDN pode ajudar parcialmente): respostas de API personalizadas por usuário têm chave de cache composta (URL + headers de autenticação), resultando em hit rate baixo por definição. Ainda assim, o roteamento geográfico da CDN reduz a latência de rede mesmo em MISSes — o PoP atua como proxy reverso próximo ao usuário, encaminhando para a origem mais rápido do que o usuário conseguiria diretamente.

Pull CDN vs Push CDN

  PULL CDN (mais comum)               PUSH CDN

  Requisição do usuário               Você envia o conteúdo
        │                             proativamente para os PoPs
        ▼                             antes de qualquer requisição.
  PoP verifica cache
        │ MISS                        Bom para: conteúdo grande
        ▼                             e previsível (vídeos, arquivos
  PoP busca na origem                 de download), onde o MISS
  e popula o cache                    na Pull CDN seria custoso.

  Simples de operar.                  Complexidade maior: você
  PoPs são populados sob              gerencia quais arquivos
  demanda (lazy).                     estão em quais PoPs.
  Primeiro usuário por PoP
  paga custo do MISS.

Quando usar

  • Assets estáticos com audiência global: imagens, JavaScript, CSS e fontes de qualquer produto com usuários em mais de uma região. O ganho é imediato e o esforço de configuração é baixo.
  • Streaming de vídeo e arquivos grandes: entregar vídeos a partir da origem para milhares de usuários simultâneos é inviável. A CDN distribui a carga de banda pelos PoPs e serve o conteúdo com menor buffering para o usuário final.
  • Proteção da origem contra picos de tráfego: eventos com tráfego imprevisível (lançamentos, campanhas virais) podem ser absorvidos pelos PoPs sem exigir que a origem tenha capacidade para o pico máximo.
  • DDoS mitigation: CDNs como Cloudflare e Akamai têm capacidade de absorver ataques distribuídos volumétricos na borda, antes que o tráfego malicioso chegue à infraestrutura da origem.

Quando evitar ou ter cuidado

  • Conteúdo altamente personalizado com baixa taxa de HIT: se cada usuário recebe uma resposta única e não compartilhável, a CDN atua apenas como proxy reverso geográfico — útil para reduzir latência de rede, mas sem o benefício de cache. O custo pode não compensar.
  • Dados sensíveis sem análise de compliance: armazenar dados pessoais ou sigilosos em servidores de terceiros (os PoPs da CDN) pode violar LGPD, GDPR ou requisitos internos. Respostas com Authorization ou Set-Cookie devem usar Cache-Control: private para nunca serem cacheadas nos PoPs.

Prós e contras

Prós

  • Redução de latência proporcional à distância geográfica: quanto mais distante o usuário da origem, maior o ganho com a CDN.
  • Descarga da origem: o servidor de origem processa apenas os MISSes, liberando capacidade para operações que não podem ser cacheadas.
  • Escalabilidade horizontal automática: a CDN absorve picos de tráfego sem exigir provisionamento adicional na origem.
  • Alta disponibilidade: se a origem ficar temporariamente indisponível, o PoP pode continuar servindo conteúdo cacheado (stale-while-revalidate).
  • Segurança integrada: CDNs modernas oferecem proteção contra DDoS, WAF (Web Application Firewall) e terminação TLS na borda.

Contras

  • Consistência eventual: após um deploy, usuários em PoPs diferentes podem ver versões distintas do conteúdo até o TTL expirar ou a invalidação propagar.
  • Custo de invalidação: propagar invalidações para todos os PoPs tem custo (financeiro e de tempo) e não é instantâneo.
  • Dependência de terceiro: a CDN é um ponto crítico de infraestrutura. Uma falha no provedor de CDN (como ocorreu com Fastly em 2021) pode derrubar serviços do mundo inteiro simultaneamente.
  • Complexidade de debugging: problemas de cache são difíceis de reproduzir localmente e de diagnosticar em produção — o comportamento varia por PoP, por TTL e por cabeçalhos.
  • Custo de transferência: CDNs cobram por volume de dados transferidos, o que pode ser significativo para conteúdo de vídeo ou apps com muitos assets grandes.

Armadilhas comuns

1. TTL longo sem cache busting

Configurar Cache-Control: max-age=31536000 em arquivos CSS e JavaScript sem incluir um hash na URL é uma combinação perigosa. Após um deploy, os PoPs continuam servindo a versão antiga até o TTL expirar — que pode ser um ano. Usuários que já visitaram o site têm o arquivo em cache no navegador por esse mesmo período.

Regra prática: TTL longo e cache busting via hash na URL andam juntos. TTL longo sem hash na URL é um bug de deploy esperando para acontecer. Nunca configure um sem o outro para assets que mudam entre deploys.

2. Invalidação cara e lenta tratada como solução padrão

Muitas equipes assumem que "se precisar, é só invalidar". Na prática, a invalidação manual tem custo, demora minutos para propagar e não garante consistência imediata em todos os PoPs. Planejar a estratégia de versionamento de URLs antes de precisar invalida é mais robusto — a invalidação deve ser o plano de contingência, não o fluxo normal.

3. Cachear respostas com dados de usuário

Respostas que contêm Set-Cookie, Authorization ou dados personalizados por usuário não devem ser cacheadas nos PoPs. Se o cabeçalho Cache-Control: private for omitido e a CDN for configurada para cachear por padrão, dados de um usuário podem ser servidos para outro — um vazamento de dados crítico.

  # ERRADO: resposta com dados do usuário sem marcar como privada
  HTTP/1.1 200 OK
  # sem Cache-Control → CDN pode cachear e servir para outros

  # CORRETO: dados privados não devem ir para cache da CDN
  HTTP/1.1 200 OK
  Cache-Control: private, no-store

4. CORS não configurado na origem

Assets (fontes, scripts, imagens) servidos pela CDN em um domínio diferente do site principal precisam de cabeçalhos CORS configurados no servidor de origem. Se o PoP cachear uma resposta sem os cabeçalhos CORS corretos, todos os usuários que receberem essa resposta cacheada terão falhas de carregamento no browser — e o problema só se resolve após o TTL expirar ou a invalidação ser propagada.

Arquiteturas e padrões relacionados

CDN é uma instância especializada de caching — aplica os mesmos princípios de TTL, HIT/MISS e invalidação, mas na camada de borda geográfica em vez de no servidor de aplicação. As mesmas estratégias de cache busting e TTL discutidas em Caching se aplicam diretamente à configuração de uma CDN.

Load Balancing e CDN são complementares: o load balancer distribui tráfego entre instâncias do servidor de origem para o mesmo datacenter; a CDN distribui tráfego entre regiões geográficas antes mesmo de chegar à origem. Em arquiteturas modernas, o tráfego passa pela CDN primeiro e só então chega ao load balancer da origem.

O API Gateway frequentemente opera junto com uma CDN: a CDN serve assets estáticos na borda enquanto o API Gateway gerencia autenticação, roteamento e rate limiting para as chamadas dinâmicas que precisam chegar à origem.