Um erro 504 Gateway Timeout ocorre quando um servidor atuando como gateway ou proxy não recebe uma resposta tempestiva de um servidor upstream. Diferente de 502 (resposta inválida) ou 503 (servidor indisponível), 504 especificamente indica que o servidor upstream foi muito lento para responder. Entender como ele se encaixa no conjunto de códigos de status HTTP ajuda equipes a diagnosticar mais rápido—504 sempre indica um timeout na camada do proxy, não um crash.

O Que Significa 504 Gateway Timeout
A Definição HTTP
Per a RFC 9110, 504 indica “o servidor, enquanto atuava como gateway ou proxy, não recebeu uma resposta tempestiva de um servidor upstream que precisou acessar para completar a requisição.”
Características principais:
- O proxy/gateway conectou com sucesso ao upstream
- O upstream não respondeu dentro do período de timeout
- A conexão foi estabelecida mas nenhum dado chegou
- Isto é um timeout no nível do proxy, não no nível do cliente
504 vs 502 vs 503
| Código | Significado | Diferença |
|---|---|---|
| 504 Gateway Timeout | Sem resposta do upstream | Conexão estabelecida, esperou muito |
| 502 Bad Gateway | Resposta inválida do upstream | Obteve resposta, mas estava malformada |
| 503 Service Unavailable | Servidor não pode lidar com requisição | Servidor explicitamente recusou ou sobrecarregado |
Causas Comuns de 504 Gateway Timeout
1. Queries de Banco Lentas
A aplicação espera por uma query lenta:
-- Query demorando mais que o timeout do proxySELECT * FROM large_table WHERE complex_conditions;-- Tempo de execução: 120 segundos-- Timeout do proxy: 60 segundos2. Chamadas a APIs Externas
Esperando por serviços terceiros lentos:
// API externa demorando muitoconst response = await fetch('https://slow-api.example.com/data');// Tempo de resposta: 90 segundos// Timeout do proxy: 30 segundos3. Computação Pesada
Processamento intensivo de CPU bloqueando o event loop:
// Computação pesada síncronaconst result = calculateLargeDataset(data);// Leva 45 segundos4. Timeout do Proxy Muito Curto
A configuração de timeout não corresponde aos requisitos da carga de trabalho:
# Timeout padrão pode ser muito curtoproxy_read_timeout 60s; # Padrão em muitas configurações5. Problemas de Rede
Perda de pacotes ou alta latência entre proxy e upstream:
- Links de rede congestionados
- Chamadas cross-region
- Overhead de VPN ou túnel
6. Esgotamento de Recursos
O servidor upstream está sobrecarregado:
- CPU a 100% por períodos prolongados
- Pressão de memória causando swap
- Saturação de I/O de disco
Troubleshooting de Erros 504
Passo 1: Identifique a Camada do Timeout
Cliente → [CDN](/pt-br/learning/cdn/o-que-e-uma-cdn/) → [Load Balancer](/pt-br/learning/performance/o-que-e-balanceamento-de-carga/) → Servidor App → Banco de Dados ↑ ↑ ↑ ↑ timeout timeout timeout query lentaCada camada tem seu próprio timeout. O erro vem de qualquer uma que timeout primeiro.
Passo 2: Verifique Logs da Aplicação
# Verifique operações lentasgrep -E "(timeout|slow|duration)" /var/log/app/app.log
# Procure tempos de query de bancogrep "query.*took.*ms" /var/log/app/database.logPasso 3: Verifique Logs do Proxy/Gateway
Nginx:
tail -f /var/log/nginx/error.log# Procure por: "upstream timed out"# Procure por: "read timed out"HAProxy:
tail -f /var/log/haproxy.log# Procure por: flags "sH" ou "cH" para timeoutsAWS ALB/ELB:
Verifique métricas CloudWatch para TargetResponseTime e HTTPCode_Target_5XX.
Azion:
Real-Time Events → filtrar por status 504# Verifique upstream_response_time para identificar qual upstream está atingindo o timeout# Correlacione com Real-Time Metrics → Edge Application → Request TimePasso 4: Verifique Performance do Banco
-- PostgreSQL: Encontre queries lentasSELECT query, calls, total_time, mean_timeFROM pg_stat_statementsORDER BY mean_time DESCLIMIT 10;
-- MySQL: Verifique lista de processosSHOW FULL PROCESSLIST;Passo 5: Profile Performance da Aplicação
# Use ferramentas APM para identificar transações lentas# Node.js: flag --prof# Python: cProfile# Java: JProfiler, YourKitGuia de Configuração de Timeouts
Timeouts Nginx
location /api/ { proxy_pass http://backend;
# Tempo para estabelecer conexão proxy_connect_timeout 10s;
# Tempo para enviar requisição ao upstream proxy_send_timeout 60s;
# Tempo para ler resposta do upstream proxy_read_timeout 60s;}Timeouts do Servidor de Aplicação
Node.js:
server.setTimeout(120000); // 2 minutosserver.keepAliveTimeout = 65000;Timeouts de Banco de Dados
PostgreSQL:
SET statement_timeout = '60s';MySQL:
SET SESSION max_execution_time = 60000;Timeouts do Cliente
O timeout do cliente deve ser maior que todos os timeouts upstream combinados:
Timeout cliente > Timeout CDN > Timeout LB > Timeout AppComo Corrigir Erros 504
1. Aumente Timeouts (Quando Apropriado)
# Apenas aumente se a operação legitimamente demora maisproxy_read_timeout 120s;Atenção: Não mascare problemas subjacentes com timeouts maiores. Investigue operações lentas primeiro.
2. Otimize Operações Lentas
Queries de banco:
-- Adicione índicesCREATE INDEX idx_user_email ON users(email);
-- Use hints de queryEXPLAIN ANALYZE SELECT ...;Código da aplicação:
// Use [caching](/pt-br/learning/cdn/o-que-e-http-caching/)const cached = await cache.get(key);if (cached) return cached;
// Pagine resultados grandesconst results = await Model.findAll({ limit: 100, offset: page * 100 });3. Implemente Processamento Assíncrono
Mova operações longas para jobs em background:
app.post('/api/process', async (req, res) => { // Inicie job e retorne imediatamente const job = await queue.add('process', req.body);
// Retorne 202 Accepted com ID do job res.status(202).json({ jobId: job.id, status: 'processing', statusUrl: `/api/jobs/${job.id}` });});
app.get('/api/jobs/:id', async (req, res) => { const job = await queue.getJob(req.params.id); res.json({ status: job.state, result: job.returnvalue });});4. Use Respostas Streaming
Para geração de dados de longa duração:
app.get('/api/export', (req, res) => { res.setHeader('Content-Type', 'text/csv'); res.setHeader('Transfer-Encoding', 'chunked');
// Stream dados conforme gerados stream.pipe(res);});5. Adicione Circuit Breakers
Falhe rápido quando upstream está consistentemente lento:
const breaker = new CircuitBreaker(callUpstream, { timeout: 5000, errorThresholdPercentage: 50, resetTimeout: 30000});
breaker.fire() .catch(() => res.status(503).json({ error: 'Serviço temporariamente indisponível' }));Perguntas Frequentes
Qual a diferença entre 504 e 502? 504 significa que o upstream não respondeu a tempo. 502 significa que o upstream respondeu mas a resposta era inválida.
Qual a diferença entre timeout do cliente e 504? Timeout do cliente é o navegador desistindo. 504 é o proxy/gateway desistindo antes do cliente.
Devo tentar novamente em 504? Sim, mas apenas para métodos idempotentes (GET, PUT, DELETE). Use backoff exponencial.
Como configuro timeouts no Kubernetes? Use timeoutSeconds em probes e configure readinessProbe apropriadamente.
Qual um valor de timeout razoável? Depende da sua carga de trabalho. Chamadas API: 30-60s. Queries de banco: 5-30s. Uploads de arquivos: maior.
Por que vejo 504 apenas sob carga? Esgotamento de recursos causa respostas lentas. Verifique limites de CPU, memória e pool de conexões.