504 Gateway Timeout: backends lentos, tempos limite e 502 x 503 x 504
Um 504 Gateway Timeout significa que um proxy alcançou o seu backend, esperou por uma resposta e desistiu antes que ela chegasse. Nada travou e nada recusou a requisição: alguma coisa atrás do proxy é mais lenta do que o proxy está disposto a esperar.
O que um 504 informa
A RFC 9110 define o 504 para um servidor atuando como gateway ou proxy que não recebeu uma resposta em tempo hábil de um servidor upstream que precisava acessar. O que é "em tempo hábil" fica definido pela configuração, não pela especificação, então um 504 é sempre uma afirmação sobre duas coisas ao mesmo tempo: quão lento o backend foi e qual limite o proxy tinha configurado.
Isso tem uma consequência prática importante. Quando um proxy devolve 504, o backend normalmente continua trabalhando na requisição. A conexão com o cliente acabou, mas a consulta lenta continua rodando, o relatório continua sendo gerado e os recursos continuam ocupados. É por isso que uma onda de 504 muitas vezes piora o servidor: cada requisição abandonada deixa trabalho para trás, e a fila cresce mais rápido do que esvazia.
504 contra 502 contra 503
| 502 Bad Gateway | 503 Service Unavailable | 504 Gateway Timeout | |
|---|---|---|---|
| O que aconteceu | O backend deu uma resposta inválida ou fechou a conexão | O servidor recusou o trabalho de propósito | O backend aceitou o trabalho e nunca respondeu a tempo |
| Estado do backend | Fora do ar, travando ou falando o protocolo errado | No ar, mas sobrecarregado ou em manutenção | No ar e ocupado, ainda processando |
| Velocidade da resposta | Normalmente imediata | Normalmente imediata | Lenta, chega no limite do tempo |
| Linha de log típica | connect() failed ou upstream prematurely closed connection | Regra de manutenção, ou nenhum upstream saudável | upstream timed out (110: Connection timed out) |
Retry-After | Incomum | Comum e recomendado | Incomum |
| Primeiro lugar a olhar | O processo do backend está rodando? | Capacidade, sinalizadores de manutenção, verificações de saúde | Consultas lentas e dependências lentas |
Na prática, um 502 falha rápido, um 503 recusa educadamente e um 504 faz você esperar antes. O guia dedicado ao 502 e a visão geral dos 5xx cobrem os outros dois por completo.
Por que o backend está lento demais
- Consultas lentas ao banco de dados. Um índice que falta, uma consulta que cresceu junto com os dados, um padrão N+1 dentro de um laço, ou disputa por locks sob concorrência. A causa mais comum de todas.
- Chamadas lentas a terceiros. Uma requisição de saída a uma API sem tempo limite próprio herda o pior dia do serviço remoto e o repassa aos seus visitantes.
- Partidas frias. A primeira requisição depois de uma escalada, do início de um contêiner ou de um período ocioso paga pela inicialização, pela abertura de conexões e pelo aquecimento do cache, tudo de uma vez.
- Trabalho realmente pesado em uma requisição web. Geração de relatórios, exportações, processamento de imagens ou importações em lote tratados de forma síncrona vão acabar ultrapassando qualquer tempo limite razoável.
- Disputa por recursos. CPU saturada, pressão de memória e uso de swap deixam toda requisição mais lenta, então as mais demoradas cruzam o limite primeiro.
- Tempos limite apertados demais. Se um endpoint legitimamente precisa de mais tempo do que o proxy permite, o bug está na configuração, não no código.
- Problemas de rede entre os saltos. Perda de pacotes ou atrasos na resolução de DNS do endereço upstream somam latência que não aparece nas medições da aplicação.
Como diagnosticar e corrigir um 504
- Meça o tempo até o erro. O atraso antes de um 504 normalmente coincide com o tempo limite configurado, o que indica qual salto o produziu:
Um 504 em quase exatamente 60 segundos aponta para um tempo limite de leitura padrão de proxy. Um em 30 ou 100 segundos aponta para o componente configurado com esse número, muitas vezes uma CDN e não o seu próprio proxy.curl -sS -o /dev/null -w "%{http_code} %{time_total}s\n" https://example.com/slow-page - Descubra se é um endpoint ou todos. Uma URL lenta é problema da aplicação. Tudo lento ao mesmo tempo é saturação de recursos ou uma dependência falhando.
- Leia o log de erros do proxy. No nginx a linha é explícita:
Ela nomeia o upstream e a fase, o que separa uma conexão lenta de uma resposta lenta.[error] upstream timed out (110: Connection timed out) while reading response header from upstream, upstream: "http://127.0.0.1:8080/" - Cronometre o backend diretamente, sem o proxy. Se a mesma requisição leva 90 segundos contra a origem, o proxy está dizendo a verdade e a correção pertence à aplicação.
- Faça o profiling do caminho lento. Olhe o log de consultas lentas e depois os rastros da aplicação. A maioria dos 504 se resume a uma consulta ou a uma chamada de saída.
- Corrija a causa antes do tempo limite. Adicione o índice, coloque o resultado caro em cache, ou mova o trabalho realmente longo para uma tarefa em segundo plano que responde na hora e informa o progresso à parte.
- Aumente o tempo limite só quando o trabalho é legitimamente longo, e aumente de forma consistente em todos os saltos. Um limite de 30 segundos na CDN torna inútil um tempo limite de 120 segundos na origem.
- Defina tempos limite nas suas próprias chamadas de saída para que uma dependência lenta falhe rápido com um erro claro em vez de consumir um worker até o proxy desistir.
O tempo de resposta é o aviso antecipado
Um 504 é o estado final de uma lentidão que vinha se acumulando havia um tempo. Os tempos de resposta sobem de meio segundo para dois segundos, depois para dez, e ninguém percebe até as requisições começarem a cruzar o limite. Uma verificação HTTP programada registra o tempo de resposta de cada execução junto com o código de status, então a tendência aparece em um gráfico muito antes do primeiro tempo esgotado, e o alerta chega na primeira falha real em vez de depois que a fila de suporte enche. Verificar de várias regiões ajuda também, porque uma rota rápida a partir de um continente e lenta a partir de outro aponta para o caminho de rede ou para a configuração de borda, não para o seu banco de dados.