Erro 504 Gateway Timeout: achar o que está lento
· 7 min de leitura
O que o erro significa
Com um 504, o servidor web da frente (nginx, Apache, um balanceador de carga, uma CDN) desiste da aplicação atrás dele: o pedido foi repassado e o backend ainda estava trabalhando quando o contador da frente chegou a zero. A diferença para o 502 Bad Gateway: o backend está acessível, só está lento demais. Timeouts habituais: 60 segundos no nginx (fastcgi_read_timeout, proxy_read_timeout) e no Apache (ProxyTimeout), 100 segundos no Cloudflare, que no plano gratuito não dá para mudar.
Aumentar o timeout raramente é a solução. Alguma coisa está demorando demais, e essa coisa precisa ser encontrada.
Causas frequentes
- Uma consulta SQL lenta. Um plugin do WordPress que conta as linhas de uma tabela enorme a cada página, um índice faltando, uma tabela
wp_optionslotada de transients vencidos. Cada pedido espera, e sob carga as esperas se somam. - Uma chamada externa que fica pendurada. A aplicação consulta um meio de pagamento, um serviço de e-mail, uma API de previsão do tempo ou um servidor de licenças, e esse serviço está lento ou fora do ar. Sem um timeout próprio, sua página espera junto com ele.
- Workers de menos. Todos os workers do PHP-FPM estão presos em pedidos lentos; os novos entram na fila até o servidor da frente desistir. Visto de fora, é um timeout, mesmo que cada pedido sozinho fosse rápido.
- Cron ou backup em primeiro plano. Um plugin de backup, uma importação, um sitemap com 50.000 URLs: gerados dentro de um pedido web, estouram qualquer timeout.
- Disco ou swap. Falta memória no servidor, ele usa swap e tudo fica dez vezes mais lento: carga alta, processador pouco ocupado.
- Rede entre o servidor da frente e o backend. Um balanceador em um data center, o backend em outro, um firewall que descarta pacotes em silêncio. Raro, mas um 504 em todo pedido com um backend ocioso aponta para isso.
Se você é visitante
Recarregue daqui a um minuto. Se o site está lento em vez de fora do ar, teste outra página; talvez a culpa seja de uma única página pesada.
Se o site é seu: verifique primeiro
Abra o website down checker: ele mostra o código HTTP e o tempo de resposta vistos de fora. Um site que hoje responde em 30 segundos amanhã, sob carga, mostra um 504.
No seu servidor, o tempo perdido se procura aqui:
# os workers estão se acumulando?
sudo tail -n 30 /var/log/nginx/error.log | grep -E 'timed out|timeout'
# o que o PHP está fazendo? (exige pm.status_path no pool)
curl -s 'http://127.0.0.1/fpm-status?full' | grep -E 'state|request URI|duration' | head -40
# MySQL/MariaDB: quais consultas estão rodando e há quanto tempo?
sudo mysql -e 'SHOW FULL PROCESSLIST;'
# memória e swap
free -m
vmstat 1 5
Uma lista cheia da mesma consulta ou colunas si/so diferentes de zero dizem o nome da causa.
Soluções no seu servidor
1. Ativar o log de consultas lentas e corrigir a consulta
SET GLOBAL slow_query_log = 1;
SET GLOBAL long_query_time = 2;
SET GLOBAL slow_query_log_file = '/var/log/mysql/slow.log';
Depois de alguns minutos, sudo mysqldumpslow -s t /var/log/mysql/slow.log | head lista as piores consultas. Crie o índice que falta ou troque o plugin que dispara a consulta. No WordPress, a tabela de opções inchada é um clássico:
wp transient delete --all
wp db query "SELECT option_name, LENGTH(option_value) AS size FROM wp_options WHERE autoload='yes' ORDER BY size DESC LIMIT 20;"
Tudo o que tem centenas de kilobytes e é carregado automaticamente a cada pedido é candidato a sair.
2. Dar um timeout às chamadas externas
Toda chamada HTTP da sua aplicação precisa de um timeout próprio, menor que o do servidor web. Em PHP com cURL: CURLOPT_CONNECTTIMEOUT em 5 e CURLOPT_TIMEOUT em 10. No WordPress, wp_remote_get() aceita um argumento timeout; muitos plugins deixam o padrão e esperam para sempre. Se um serviço de terceiros está fora do ar, a página deve sair em versão reduzida (o formulário sem o valor do frete ao vivo), não morrer.
3. Tirar os processos longos do pedido
Backups, importações, exportações, sitemaps grandes e envios de e-mail vão para um cron job ou uma fila, não para uma página. No WordPress, desative o pseudo-cron e instale o de verdade:
// wp-config.php
define('DISABLE_WP_CRON', true);
# crontab -e
*/5 * * * * cd /var/www/example.com && wp cron event run --due-now >/dev/null 2>&1
4. Ajustar os timeouts, com medida
Se uma página precisa mesmo de mais tempo (uma exportação, um relatório), aumente o timeout só para ela, não globalmente:
location = /wp-admin/export.php {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/run/php/php8.3-fpm.sock;
fastcgi_read_timeout 300;
}
Apache com PHP-FPM: ProxyTimeout 300 dentro de um bloco <Location>. Coloque o max_execution_time do PHP no mesmo valor; senão o PHP desiste primeiro com um 500. Depois sudo nginx -t && sudo systemctl reload nginx.
5. Parar de usar swap
ps aux --sort=-%mem | head
Se cada worker do PHP-FPM ocupa 150 MB e você sobe 30 em um servidor de 4 GB, a conta não fecha. Reduza pm.max_children, adicione memória ou conserte o plugin que devora tudo. Em um servidor que não usa swap, a maioria dos 504 desaparece.
6. Colocar um cache
Um cache de páginas (o cache FastCGI do nginx, um plugin do WordPress, Varnish) atende os visitantes que voltam sem tocar no PHP nem no banco de dados. A maioria dos 504 sob carga some assim que a página inicial e as mais visitadas saem do cache.
Se o problema está na sua hospedagem
Em uma hospedagem compartilhada você pode corrigir consultas lentas e plugins, mas não os timeouts do servidor nem a carga dos vizinhos. Envie à sua hospedagem:
Prezados, meu site example.com está devolvendo “504 Gateway Timeout” desde aproximadamente 16h (UTC). Páginas que antes carregavam em menos de dois segundos agora estouram o timeout. Não alterei nada. Poderiam verificar se o servidor de banco de dados ou o pool PHP da minha conta está sobrecarregado, ou se outra conta no servidor está gerando muita carga, e me dizer o que encontraram?
Para não acontecer de novo
Um 504 é um site lento que ficou ainda mais lento, e o tempo de resposta se mede muito antes do timeout. As verificações do site registram esse tempo a cada passagem; coloque um alerta nele e você verá a tendência muito antes de os visitantes verem um erro. O monitoramento de servidores acrescenta carga, memória e swap por dentro.
Fora do ar? Nós resolvemos. No seu servidor ou em uma hospedagem compartilhada com acesso SSH, o Deep Fix, o reparo aprofundado, encontra a consulta lenta ou a chamada pendurada e corrige, 24 horas por dia, inclusive nos fins de semana, em blocos de 15 minutos, preço visível antes do pedido, a estimativa é o valor máximo; o Quick Fix, a preço fixo, reinicia um serviço parado.
E agora
Verifique de fora
O site está fora do ar para todos ou só para você, e o que o servidor responde? Grátis, sem cadastro.
Verificador de site fora do arFora do ar? Nós resolvemos.
No seu servidor ou em uma hospedagem compartilhada com acesso SSH: Quick Fix a preço fixo para as causas mais comuns, Deep Fix cobrado em blocos de 15 minutos para todo o resto, 24/7. Preço visível antes do pedido.
Pedir um reparoOutros guias
- Site fora do ar: o que fazer nos primeiros 15 minutos
- Servidor fora do ar: o que verificar e em que ordem
- Erro 500 Internal Server Error: achar a causa nos logs e colocar o site de volta no ar
- Erro 502 Bad Gateway: achar a causa e resolver
- Erro 503: sobrecarga, manutenção ou limite da hospedagem?
- Erro 521 e 522 do Cloudflare: o servidor de origem não responde
- DNS_PROBE_FINISHED_NXDOMAIN: o domínio não responde mais
- ERR_CONNECTION_REFUSED: o servidor recusa a conexão
- ERR_CONNECTION_TIMED_OUT: o servidor não responde a tempo
- O que significa “Sua conexão não é particular” e como resolver
- ERR_SSL_PROTOCOL_ERROR: a conexão segura falha antes do certificado
- ERR_TOO_MANY_REDIRECTS: achar o loop de redirecionamentos e fechá-lo
- Erro 403 Forbidden: o que bloqueia o acesso ao seu site
- ERR_NAME_NOT_RESOLVED: o nome do site não é encontrado
- “Erro ao estabelecer conexão com o banco de dados” no WordPress: causa e solução