Seu site carrega em 300 milissegundos no seu sistema local. Você implanta uma CDN (content delivery network), um sistema de servidores distribuídos que guarda cópias do seu conteúdo mais perto dos usuários. Tudo parece rápido. Você considera o problema resolvido.
Então um usuário em outro continente relata lentidão para carregar o site. Seu painel de monitoramento não mostra nenhum problema. Isso é confuso, mas tem uma explicação simples: um teste feito a partir de uma única máquina só mostra o desempenho do site naquela localização. Ele não diz como o site se comporta em qualquer outro lugar.
Este guia mostra como testar o desempenho de CDN pela linha de comando no Linux. Você vai aprender a medir a velocidade da conexão, verificar se a CDN está servindo conteúdo em cache e testar o desempenho a partir de várias regiões. Todas as ferramentas usadas aqui rodam em um sistema Linux padrão.
Ao final, você vai conseguir responder a estas perguntas:
- Quão rápido o DNS resolve seu domínio?
- Quanto tempo leva para estabelecer a conexão?
- Quanto tempo leva o TLS handshake?
- Quão rápido o primeiro byte de conteúdo chega?
- A CDN está realmente servindo a requisição a partir do cache?
- O desempenho varia por região?
Por que a linha de comando funciona bem para isso
Ferramentas baseadas em navegador mostram o tempo total de carregamento. Elas misturam atrasos de rede, execução de JavaScript e tempo de renderização. Isso dificulta isolar onde o tempo é realmente gasto.
O utilitário de linha de comando curl resolve esse problema. Ele mede cada etapa de uma requisição separadamente. Também ignora a renderização do navegador, então os números refletem apenas a rede e a resposta do servidor.
Aqui está um comando básico que mede uma única requisição:
curl -sS -o /dev/null -w \
'DNS: %{time_namelookup}s
Connect: %{time_connect}s
TLS: %{time_appconnect}s
TTFB: %{time_starttransfer}s
Total: %{time_total}s
IP: %{remote_ip}
' \
https://example.com/
Este comando usa curl para medir e exibir métricas detalhadas de tempo para uma conexão HTTPS até example.com, sem baixar o conteúdo real da página.
Saída esperada:
DNS: 0.049033s
Connect: 0.078883s
TLS: 0.114448s
TTFB: 0.150471s
Total: 0.150763s
IP: 104.20.23.154
Este comando descarta o corpo da resposta (-o /dev/null) e imprime apenas os dados de tempo. Execute-o contra seu próprio site para obter sua primeira medição real.
Detalhamento de cada parte:
As métricas exibidas:
- DNS (
time_namelookup) — tempo para resolver o nome de domínio para um IP - Connect (
time_connect) — tempo para estabelecer a conexão TCP - TLS (
time_appconnect) — tempo para o handshake TLS/SSL - TTFB (
time_starttransfer) — tempo até o primeiro byte, quando a resposta do servidor começa a chegar - Total (
time_total) — tempo total da requisição/resposta - IP (
remote_ip) — o endereço IP usado pela conexão
É útil para:
- Monitoramento de desempenho — verificar com que rapidez um servidor responde
- Depuração — identificar qual parte da conexão está lenta: DNS, rede, TLS ou processamento do servidor
- Health checks — verificar se um servidor está acessível e respondendo sem baixar conteúdo grande
Transformando uma requisição em um perfil de desempenho
Um número único como “1.2 segundos” não diz muita coisa. Uma requisição acontece em etapas. Cada etapa pode ser medida separadamente.
A sequência é:
DNS lookup
↓
TCP connection
↓
TLS handshake
↓
Request sent
↓
First byte received
↓
Transfer completed
Cada variável de tempo do curl corresponde a uma dessas etapas:
time_namelookup: tempo para resolver o nome de domínio para um endereço IPtime_connect: tempo para abrir umaTCP connectionaté esse IPtime_appconnect: tempo para concluir o TLS handshake, o processo que estabelece uma conexão criptografadatime_starttransfer: tempo até o primeiro byte da resposta chegar, também conhecido como time to first byte (TTFB)time_total: tempo para a requisição inteira terminar
Essa divisão permite encontrar a causa real da lentidão em vez de adivinhar:
- Um tempo de DNS alto aponta para um problema de DNS.
- Um tempo de conexão alto aponta para um problema de rede ou roteamento.
- Um TTFB alto com tempo de conexão normal aponta para um servidor ou resposta de CDN lenta.
- Uma diferença grande entre TTFB e tempo total aponta para uma resposta grande ou uma transferência lenta.
A CDN está realmente servindo a requisição?
Uma resposta rápida nem sempre significa que a CDN está fazendo o trabalho dela. A CDN pode estar encaminhando todas as requisições para o servidor de origem em vez de servir do cache. Você pode verificar isso com os cabeçalhos de resposta.
Execute este comando para ver os cabeçalhos sem baixar o corpo:
curl -s -o /dev/null -D - https://example.com/ | grep -iE '(cache|age|served-by)'
Exemplo de saída:
age: 6687
cf-cache-status: HIT
Isso envia uma requisição GET normal e descarta o corpo, imprimindo apenas os cabeçalhos. Evite curl -I para essa verificação. Essa flag envia uma requisição HEAD em vez de GET, e algumas CDNs tratam requisições HEAD de maneira diferente de GET, já que usuários reais quase sempre enviam GET. Testar com HEAD pode mostrar um status de cache que não corresponde ao que seus usuários veem de fato.
Procure um cabeçalho de status de cache. O nome do cabeçalho depende da sua CDN:
- Cloudflare usa
CF-Cache-Status, com valores comoHIT,MISS,EXPIRED,REVALIDATED,BYPASSouDYNAMIC. - Fastly usa
X-Cache, com valoresHITouMISS, além deX-Cache-Hits, que mostra quantas vezes aquele objeto foi servido do cache. A Fastly também defineX-Served-Bypara nomear o nó de cache específico, embora esse cabeçalho sozinho não indique hit ou miss. - Amazon CloudFront usa
X-Cache, formatado comoHit from cloudfrontouMiss from cloudfront. - Akamai e Azure CDN legado usam valores de
X-CachecomoTCP_HITeTCP_MISS, mas expõem essas informações de diagnóstico de forma diferente. O Azure CDN (clássico) geralmente retornavaX-Cacheem respostas comuns. OX-Cacheda Akamai é primariamente um cabeçalho de diagnóstico e normalmente é solicitado explicitamente, historicamente por meio de um cabeçalho Pragma comoPragma: akamai-x-cache-on(opcionalmente combinado comakamai-x-get-cache-key). Portanto, a ausência deX-Cacheem uma resposta comum da Akamai não deve ser interpretada como cache miss. A Akamai hoje recomenda o mecanismo Enhanced Debug autenticado para esse fim.
Um cabeçalho Age, quando presente, mostra há quantos segundos o conteúdo está armazenado no cache.
Uma resposta rápida com MISS significa que a CDN encaminhou a requisição. Uma resposta rápida com HIT significa que a CDN está realmente fazendo o trabalho dela. São duas coisas diferentes, e apenas uma delas prova que a CDN está funcionando como esperado.
Uma ressalva ao testar dessa forma:
O curl não envia os mesmos cabeçalhos que um navegador envia por padrão, como Accept-Encoding para compressão.
Algumas CDNs, incluindo CloudFront, incluem uma versão normalizada de Accept-Encoding na chave de cache quando a compressão está habilitada. Sem esse cabeçalho, o curl é tratado como se estivesse pedindo conteúdo sem compressão, que fica armazenado como uma cópia separada da versão comprimida que os navegadores recebem. Isso pode produzir um miss na sua primeira requisição com curl mesmo quando os navegadores estão recebendo hit de forma consistente, já que sua requisição e a de um navegador estão encontrando cópias diferentes em cache.
Se seu teste com `ZXQPROTECT mostra um miss, mas usuários reais veem tempos de carregamento rápidos, vale a pena verificar essa incompatibilidade antes de concluir que existe um problema real de cache.
Nota sobre Azure: a Microsoft está aposentando o Azure CDN Standard da Microsoft (clássico) em favor do Azure Front Door. Desde 15 de agosto de 2025, o Azure CDN da Microsoft (clássico) não aceita mais criação de novos perfis nem integração de domínios, e a aposentadoria completa está prevista para 30 de setembro de 2027. Implantações existentes podem continuar operando até a aposentadoria, portanto o comportamento do
X-Cachedescrito acima continua relevante ao testar um endpoint CDN clássico. Para implantações novas, use o Azure Front Door Standard ou Premium; o Front Door também expõeX-Cache, inclusive com valores comoTCP_HIT,TCP_REMOTE_HITeTCP_MISS, mas possui cabeçalhos e convenções de diagnóstico adicionais e atuais.
Uma medição não é suficiente
Uma única requisição pode enganar. A primeira requisição a uma URL pode encontrar o cache vazio, enquanto as seguintes encontram o cache aquecido. As condições de rede também mudam a cada instante.
Execute a mesma requisição várias vezes em um loop:
for i in {1..10}; do
curl -sS -o /dev/null -w \
'%{http_code} %{time_starttransfer}s %{time_total}s\n' \
https://example.com/
done
Exemplo de saída:
200 0.146150s 0.146868s
200 0.231786s 0.232220s
200 0.077217s 0.077753s
200 0.240986s 0.241477s
200 0.682164s 0.682240s
200 0.132748s 0.133461s
200 0.410818s 0.933873s
200 0.087598s 0.088383s
200 0.256964s 0.745285s
200 0.679765s 0.882171s
Observe o padrão dos dez resultados, não apenas uma linha. Um cache frio costuma mostrar uma primeira requisição mais lenta seguida por outras mais rápidas.
Números consistentes sugerem um cache estável. Oscilações grandes sugerem um problema que merece investigação. O valor mediano costuma ser mais útil que a média, porque um único valor discrepante e lento pode distorcer a média sem refletir o desempenho típico.
Entendendo o que o cache da CDN realmente faz
O trabalho principal de uma CDN é armazenar em cache, não apenas ficar fisicamente perto do usuário. Conhecer alguns termos facilita o restante deste guia.
- Cache hit: a CDN encontrou uma cópia válida e armazenada do conteúdo e a serviu diretamente.
- Cache miss: a CDN não encontrou uma cópia válida e precisou buscá-la no servidor de origem.
- TTL (time to live): por quanto tempo a CDN mantém uma cópia em cache antes de considerá-la expirada.
- Cache key: o conjunto de valores que a CDN usa para decidir se duas requisições devem receber o mesmo conteúdo em cache.
- Origin request: uma requisição que a CDN envia ao seu servidor real, feita somente em caso de cache miss.
- Edge location: um servidor da CDN posicionado perto dos usuários, onde o conteúdo em cache é armazenado e servido.
A cache key importa mais do que a maioria das pessoas espera. Se a sua CDN inclui itens desnecessários na cache key — cabeçalhos extras, cookies ou parâmetros de query string — ela cria mais variantes de cache.
Mais variantes significam mais cache misses, porque menos requisições correspondem a uma cópia já existente. Manter a cache key simples normalmente melhora o hit ratio, o percentual de requisições servidas do cache em vez do servidor de origem.
Um desvio específico do Linux: IPv4 vs IPv6
A maioria dos sistemas hoje suporta IPv4 e IPv6. O desempenho pode ser diferente entre os dois, dependendo do caminho de rede e do roteamento da sua CDN.
Teste cada versão separadamente:
curl -4 -sS -o /dev/null -w '%{time_total}\n' https://example.com/
curl -6 -sS -o /dev/null -w '%{time_total}\n' https://example.com/
Se um dos dois for visivelmente mais lento, a diferença pode indicar um problema de roteamento específico daquele protocolo. Vale a pena verificar, pois algumas redes tratam IPv6 com menos eficiência do que IPv4, ou o contrário.
Verificando o desempenho de HTTP/3
A maioria das CDNs grandes hoje suporta HTTP/3, uma versão do protocolo que roda sobre QUIC em vez de TCP. QUIC é um protocolo de transporte construído sobre UDP. Ele elimina um problema chamado head-of-line blocking, em que um único pacote perdido atrasa todos os fluxos de uma conexão. Isso pode tornar o HTTP/3 visivelmente mais rápido em redes com perda de pacotes, como conexões móveis.
Sua build do curl precisa de suporte a QUIC para testar isso, e esse suporte não vem incluído na maioria das instalações padrão de pacotes Linux. Verifique se a sua build tem suporte:
curl --version | grep -i http3
Se faltar suporte a HTTP/3, você ainda pode confirmar que o servidor oferece o protocolo verificando o cabeçalho de resposta Alt-Svc:
curl -s -o /dev/null -D - https://example.com/ | grep -i alt-svc
Se a sua build do curl suporta HTTP/3, compare diretamente com HTTP/2:
FORMAT='Protocol: %{http_version} Total: %{time_total}s\n'
curl -s -o /dev/null --http2 -w "$FORMAT" https://example.com/
curl -s -o /dev/null --http3 -w "$FORMAT" https://example.com/
Confira o valor de %{http_version} na saída para confirmar qual protocolo foi usado de fato.
Quando você solicita --http3, o curl tenta primeiro uma conexão QUIC e depois volta automaticamente para HTTP/2 se o QUIC falhar ou ficar lento demais. Esse fallback acontece silenciosamente, então a requisição ainda é bem-sucedida mesmo quando o HTTP/3 não funciona. O campo de versão na saída é a única forma confiável de saber qual protocolo foi usado.
DNS é parte do caminho, não apenas uma consulta
A resolução de DNS não é uma etapa separada do desempenho da CDN. Ela é parte do caminho. Muitas CDNs usam DNS para direcionar o usuário a uma edge location próxima, então o endereço IP devolvido por uma consulta DNS pode variar conforme a sua localização.
Verifique a resolução atual com dig:
dig example.com
Para uma saída mais curta, mostrando apenas o endereço IP resolvido:
dig +short example.com
Tenha três coisas separadas na cabeça: a etapa de resolução de DNS, o endereço IP retornado e a edge location real da CDN que acaba atendendo sua requisição HTTP.
Um comando dig informa as duas primeiras. Ele não confirma qual instalação física atendeu à requisição. Os cabeçalhos de resposta, vistos antes, são uma fonte melhor para isso.
A constatação: uma máquina, um ponto de vista
Todos os testes até aqui saíram de uma única máquina, em uma única localização. Essa é a limitação central de tudo o que foi visto até agora. Suas medições são precisas, mas descrevem apenas o desempenho a partir do lugar onde você está.
Isso importa porque as CDNs encaminham usuários para edge locations diferentes conforme a origem da requisição. Uma CDN com bom desempenho para você pode encaminhar um usuário em outra região para uma edge location lenta ou mal configurada, e você jamais veria isso da sua própria máquina.
O próximo passo é executar os mesmos testes de várias regiões e comparar os resultados. Você não procura o número mais rápido, e sim padrões:
- Uma região é consistentemente mais lenta que as outras?
- O TTFB varia muito entre regiões?
- Regiões diferentes recebem status de cache diferentes para o mesmo conteúdo?
- Algumas regiões estão atingindo uma edge location diferente da esperada?
- O desempenho de IPv4 ou IPv6 difere por região?
Obtendo requisições de múltiplas regiões
Para testar de várias regiões, você precisa de requisições que realmente se originem dessas regiões. Há algumas formas práticas de fazer isso.
A primeira é usar infraestrutura que você já controla em outras regiões, como servidores existentes ou filiais. Isso dá controle total sobre o ambiente de teste, mas só funciona se você já tiver algo rodando nas regiões que interessam.
A segunda é provisionar máquinas virtuais efêmeras na nuvem nas regiões desejadas, com um provedor como DigitalOcean ou Hetzner. Isso funciona bem para testes ocasionais ou pontuais, embora exija tempo para criar e derrubar o ambiente a cada verificação.
A terceira opção, útil para equipes que não querem provisionar e manter servidores de teste em todas as regiões, é rotear o tráfego de teste por endpoints de proxy geograficamente distribuídos. Em alguns setups de teste, proxies rotativos dedicados podem fornecer um pool controlado de endpoints regionais para verificações repetidas, sem o custo de gerenciar infraestrutura separada em cada local.
Cada opção envolve um trade-off entre controle, esforço de configuração e frequência com que você pretende rodar os testes. Escolha a que combina com a frequência necessária e com o número de regiões que você precisa cobrir.
Construindo um teste repetível
Depois que você conseguir enviar requisições de várias regiões, combine tudo o que foi visto até aqui em um único script. Para cada requisição, registre:
- timestamp
- região
- código de status HTTP
- endereço IP remoto
- tempo de DNS
- tempo de conexão
- tempo de TLS
- TTFB
- tempo total
Um formato de saída simples pode ser assim:
timestamp,region,status,remote_ip,dns,connect,tls,ttfb,total
2026-09-05T09:00:00Z,eu-west,200,104.16.1.1,0.012,0.034,0.089,0.145,0.210
2026-09-05T09:00:00Z,ap-southeast,200,104.16.2.5,0.028,0.061,0.140,0.310,0.402
Você pode redirecionar essa saída para um arquivo CSV, para um banco de dados leve como SQLite ou para um sistema de monitoramento como Prometheus. Rodar o script em um agendamento com cron transforma uma verificação pontual em um registro contínuo de desempenho ao longo do tempo.
Interpretando os resultados
Depois de ter dados de várias requisições e regiões, use estes padrões para guiar a investigação:
- Tempo de DNS alto: verifique a configuração de DNS e o desempenho do resolvedor.
- Tempo de conexão alto, DNS normal: verifique a distância de rede e o roteamento até aquela região.
- TTFB alto, tempo de conexão normal: verifique o processamento da CDN ou do servidor de origem e o status do cache.
- TTFB baixo, tempo total alto: verifique o tamanho da resposta e a velocidade de transferência.
- Uma região consistentemente mais lenta que as outras: verifique o roteamento, o direcionamento por DNS e a cobertura da CDN naquela região.
- Alta variabilidade entre requisições repetidas: confie no padrão de muitas requisições, não em um único resultado.
Isso transforma números crus em um ponto de partida para a solução real de problemas.
O que o curl não vai dizer
O teste por linha de comando tem um limite que vale a pena deixar claro: curl mede o desempenho em nível de rede e de HTTP. Ele não executa JavaScript, não renderiza páginas, não carrega imagens na ordem que um navegador carregaria e não mede mudanças de layout.
Isso significa que o teste por CLI não é um substituto completo para testes de desempenho baseados em navegador. Ele é um complemento. Use curl para isolar problemas de rede e de servidor. Use ferramentas baseadas em navegador, como o devtools do seu navegador ou um serviço de monitoramento sintético, para medir a experiência completa do usuário, incluindo renderização e comportamento client-side.
Referência rápida
Conclusão: meça o que os usuários realmente experimentam
Uma CDN não é bem-sucedida simplesmente por estar ativada. A questão real é se ela entrega seu conteúdo de forma rápida e consistente para os usuários nos lugares onde eles realmente estão.
O fluxo de trabalho deste guia segue um padrão simples: medir, inspecionar, repetir, comparar, diagnosticar e medir de novo. Comece com uma única requisição na sua própria máquina. Verifique se a CDN está realmente servindo o cache. Repita o teste para eliminar ruído.
Depois, estenda o mesmo método para múltiplas regiões, usando sua própria infraestrutura, máquinas de teste na nuvem ou endpoints de proxy distribuídos, dependendo da frequência com que você precisa verificar e de quantas regiões você precisa cobrir.
As ferramentas de linha de comando oferecem esse fluxo de trabalho inteiro sem software de monitoramento pago. O único requisito é criar o hábito de verificar.




