Rede lenta ou servidor lento? Como separar os dois
O cliente diz que o site está lento, o servidor mostra CPU em 15% e todo mundo fica sem saber onde procurar. A separação entre latência de rede e lentidão de aplicação leva dez minutos.
Equipe EasyOps Cloud · · 7 min de leitura
"O site está lento." É o relato mais comum e o menos informativo que existe. O servidor mostra CPU em 15%, memória sobrando, disco tranquilo — e mesmo assim alguém do outro lado espera cinco segundos por uma página.
A causa está em um de dois lugares: o tempo que o pacote leva para ir e voltar, ou o tempo que a aplicação leva para responder depois que o pacote chegou. São problemas com sintomas idênticos e correções que não têm nada em comum. Separá-los é a primeira coisa a fazer, e leva dez minutos.
Uma requisição, sete tempos
O curl decompõe a requisição inteira e resolve a dúvida quase sempre na primeira
tentativa:
curl -w '
dns: %{time_namelookup}s
conexao: %{time_connect}s
tls: %{time_appconnect}s
1o byte: %{time_starttransfer}s
total: %{time_total}s
' -o /dev/null -s https://meusite.com.br/Cada número é acumulado desde o início, então o que importa é a diferença entre eles:
| Intervalo | O que mede | Se estiver alto |
|---|---|---|
| até dns | Resolução de nome | Problema de DNS, não do servidor |
| dns → conexao | Handshake TCP | Latência de rede pura |
| conexao → tls | Negociação TLS | Certificado grande, ou latência outra vez |
| tls → 1o byte | A aplicação pensando | O servidor é o gargalo |
| 1o byte → total | Transferência do corpo | Banda, ou resposta grande demais |
A linha decisiva é tls → 1o byte. Ela é o tempo que a sua aplicação levou para
produzir a resposta, já descontada toda a rede. Se ela for pequena e o total for
grande, pare de investigar o servidor — o problema está no caminho. Se ela
sozinha for grande, a rede está inocente.
Latência: o que é física e o que é problema
Rode a partir da máquina de quem reclama, nunca de outro servidor:
ping -c 20 meusite.com.brExiste um piso que nenhuma otimização vence, porque é distância dividida por velocidade da luz em fibra:
| Origem → destino | Latência típica |
|---|---|
| São Paulo → São Paulo | 1 a 10 ms |
| São Paulo → Nordeste | 25 a 45 ms |
| São Paulo → Virgínia (EUA) | 110 a 130 ms |
| São Paulo → Frankfurt | 190 a 220 ms |
Esses números explicam por que servidor fora do país pesa tanto. Uma página que faz vinte requisições sequenciais contra um servidor na Virgínia paga 130 ms em cada uma: 2,6 segundos só de ida e volta, com o servidor respondendo instantaneamente. O mesmo site em São Paulo gasta 200 ms no total.
É também o motivo pelo qual TLS custa caro à distância: o handshake exige idas e voltas extras antes do primeiro byte útil.
Se o seu público é brasileiro, latência é a otimização mais barata disponível — não há ajuste de código que compense a distância geográfica, e escolher a região certa resolve de uma vez.
Perda de pacote: o vilão silencioso
Latência alta é irritante e previsível. Perda de pacote é pior: causa travadas aleatórias, porque o TCP espera, retransmite e reduz a janela de envio.
O ping mostra que existe perda; o mtr mostra onde:
mtr -rwzbc 100 meusite.com.brEle envia 100 pacotes e imprime um relatório por salto, com perda e latência de cada um. A leitura tem uma armadilha importante:
- Perda em um salto do meio que some nos seguintes — não é problema. Muitos
roteadores despriorizam responder ao próprio
mtr, mas encaminham o tráfego normalmente. - Perda que começa em um salto e continua até o fim — aqui sim. O ponto onde ela começa é o trecho com problema.
- Latência que sobe e permanece alta — congestionamento a partir dali.
Só o segundo e o terceiro casos merecem ação. E vale rodar nos dois sentidos: o
caminho de ida e o de volta na internet frequentemente são diferentes, e um
problema no retorno não aparece no mtr disparado da sua ponta.
Medir banda de verdade
ping mede latência, não capacidade. Para banda, use iperf3 entre dois pontos
controlados:
# No servidor
iperf3 -s
# No cliente
iperf3 -c 203.0.113.50 -t 20 # download
iperf3 -c 203.0.113.50 -t 20 -R # uploadLembre de liberar a porta 5201 na regra de firewall durante o teste — e de fechar depois.
Um detalhe que engana muita gente: em conexão de alta latência, uma única sessão TCP não atinge a banda disponível, por causa do tamanho da janela. Teste com várias em paralelo antes de concluir que a banda está ruim:
iperf3 -c 203.0.113.50 -P 8 -t 20Se oito conexões somam bem mais que uma, a banda existe — o que falta é paralelismo, e isso é característica do protocolo, não defeito do link.
Quando a rede está boa e ainda está lento
Descartada a rede, o tempo está sendo gasto dentro da máquina. Os suspeitos, em ordem de frequência:
- Consulta ao banco sem índice. Responde em 10 ms com mil registros e em 4 segundos com um milhão. É de longe a causa mais comum de "ficou lento com o tempo".
- Chamada externa em série. Cada API de terceiro no meio da requisição soma a latência dela à sua. Uma integração lenta derruba a página inteira.
- Espera por disco. Confira com
iostat -x 2a coluna%util; próxima de 100 significa disco saturado. - Fila de conexão. Todos os workers ocupados fazem a requisição esperar antes mesmo de começar. O sintoma é latência que cresce junto com o número de usuários, sem CPU alta.
Para localizar sem instrumentação, compare a resposta de uma rota trivial com a de uma rota real:
curl -w '%{time_starttransfer}\n' -o /dev/null -s https://meusite.com.br/health
curl -w '%{time_starttransfer}\n' -o /dev/null -s https://meusite.com.br/pedidosSe /health responde em 20 ms e /pedidos em 3 segundos, o servidor está saudável
e o problema é aquela rota — quase sempre uma consulta. Se as duas demoram, o
problema é da máquina, e o diagnóstico de VPS lenta cobre o resto.
O DNS que ninguém suspeita
Aquele primeiro campo do curl, time_namelookup, merece atenção própria. DNS
lento produz um sintoma muito característico: a primeira visita demora e as
seguintes voam, porque o resultado ficou em cache.
Como isso se resolve sozinho ao testar de novo, quase ninguém consegue reproduzir — e o relato fica sendo "às vezes está lento".
dig meusite.com.br | grep 'Query time'
dig @1.1.1.1 meusite.com.br | grep 'Query time'Comparar o resolvedor configurado na máquina com um público separa as duas hipóteses. Se o padrão demora 300 ms e o público responde em 15 ms, o problema é o resolvedor, não o seu domínio.
Do lado do servidor, o DNS também morde de um jeito específico: uma aplicação que resolve o nome de um serviço externo a cada requisição paga essa latência sempre. E há um caso clássico em log de acesso — a resolução reversa:
# Nunca ligue isto em produção
# resolver_timeout e busca reversa por IP adicionam
# latência a cada requisição registradaConfira também o TTL dos seus registros. TTL muito baixo multiplica consultas e adiciona latência a cada visitante novo; TTL muito alto atrapalha na hora de mudar de servidor. Entre 300 e 3600 segundos atende à maioria dos casos, e vale reduzir temporariamente só na véspera de uma migração planejada — assunto que o apontamento de domínio cobre em detalhe.
Um teste que vale mais que a média
Média engana. Uma rota com 200 ms de média pode ter 90% das respostas em 50 ms e 10% em 1,5 segundo — e são justamente esses 10% que geram reclamação.
for i in $(seq 1 50); do
curl -w '%{time_total}\n' -o /dev/null -s https://meusite.com.br/pedidos
done | sort -n | awk '{a[NR]=$1} END {
printf "p50=%.3f p90=%.3f p99=%.3f max=%.3f\n",
a[int(NR*0.5)], a[int(NR*0.9)], a[int(NR*0.99)], a[NR]
}'Um p99 muito acima do p50 aponta para algo intermitente: garbage collector, lock
de banco, cache que expira em bloco. Já p50 e p99 próximos e ambos altos indicam
lentidão constante — mais fácil de achar e de corrigir.
Guarde esse número antes de qualquer otimização. Sem medida anterior, não há como afirmar que a mudança ajudou, e otimização sem comparação é palpite com esforço.
Vale rodar esse mesmo laço a partir de duas origens diferentes — a sua máquina e um servidor em outra rede. Quando os dois resultados coincidem, o problema é do servidor e vale para todo mundo. Quando divergem muito, o problema está no caminho de quem reclamou, e a correção não passa por mexer na aplicação.