O erro 504 Gateway Timeout significa que o servidor à frente do PHP (nginx, CDN ou proxy do alojamento) não recebeu resposta no tempo definido. O WordPress costuma ser aqui a vítima e não o culpado: o pedido fica na fila à espera de um worker PHP livre ou demora demasiado por si só. Comece pelos registos do PHP-FPM da hora da falha e depois verifique se o erro afeta o site inteiro ou apenas um endereço.
O que significa o erro 504 no WordPress
A MDN, com base no RFC 9110, define o 504 como a situação em que um servidor que atua como gateway ou proxy “não recebeu a tempo uma resposta do servidor upstream” (tradução própria). É diferente do 502 Bad Gateway: aí a resposta chegou, mas era inválida. No 504 não chegou nada.
Num alojamento WordPress típico, a cadeia é esta: navegador, opcionalmente uma CDN, nginx, PHP-FPM, base de dados e, eventualmente, cache de objetos. O código 504 é gerado pelo elo que ficou à espera. Isso já indica onde procurar. Se o nginx espera pelo PHP, o problema está no PHP, na base de dados ou na fila para o PHP. Se quem espera é a CDN, o problema está no servidor de origem.
A documentação da MDN assinala também que as causas são várias e que a correção costuma exigir análise por parte do administrador do servidor. Por isso, daqui em diante não há uma correção mágica, há uma ordem de verificações.
O 504 é culpa do alojamento ou do site
O âmbito do erro decide a questão. A tabela abaixo é um atalho de decisão, não uma sentença.
| Sintoma | Direção mais provável |
|---|---|
| 504 em todo o site, mesmo em subpáginas simples | Poucos workers PHP ou servidor sobrecarregado: alojamento ou tráfego |
| 504 apenas num endereço | Consulta lenta, plugin ou API externa chamada por esse endereço |
| 504 no wp-admin e ao guardar, o front-end funciona a partir da cache | Pedidos pesados de utilizadores com sessão iniciada, que contornam a cache |
| 504 esporádico, sempre nas mesmas horas | Tarefas agendadas, cópias de segurança ou pico de tráfego |
| 504 depois de alterar um plugin ou atualizar | Conflito de plugin ou migração da base de dados que demora demasiado |
A responsabilidade do alojamento começa onde os limites (número de workers, memória, CPU) são pequenos demais para o tráfego normal do site. A responsabilidade do site começa onde um único pedido faz tanto trabalho que bloqueia o worker durante dezenas de segundos. Na prática, muitas vezes atuam as duas coisas em simultâneo: os pedidos lentos ocupam os workers e o pool pequeno não tem folga.
Porque é que o meu site WordPress vai abaixo de poucas em poucas semanas
Em novembro de 2025, no fórum r/webdev, o dono de dois sites WordPress, ambos geridos pelo mesmo programador, perguntou sem rodeios se isto era normal:
De poucas em poucas semanas, os sites vão abaixo de repente ou deixam de funcionar como devem: ou a página não carrega, ou alguma coisa avaria. O programador diz sempre que é um problema do alojamento ou que é preciso renovar, fazer cópia de segurança ou atualizar, e depois propõe um plano anual de manutenção ou de cópias de segurança por um valor adicional.
(tradução própria, r/webdev, tópico de 2 de novembro de 2025)
O tópico recebeu dezenas de respostas. Seguem as perguntas que dele resultam e o que pode verificar por si.
A culpa é do alojamento ou do programador
As respostas dividiram-se em dois campos. Um programador que monitoriza os sites de todos os seus clientes escreve que os sites em alojamentos mais baratos “vão abaixo pelo menos uma vez por semana”, porque não aguentam o tráfego de bots (tradução própria, tomhermans, r/webdev). Outro responde que um site bem configurado num bom alojamento “praticamente NUNCA deveria ir abaixo” (tradução própria, redlotusaustin, r/webdev).
As duas coisas podem ser verdade ao mesmo tempo, e a tabela acima ajuda a separá-las. Se cada falha mostra um 502 ou um 504 em todo o site, a culpa costuma ser dos recursos: um pool PHP-FPM demasiado pequeno ou um servidor partilhado sobrecarregado. Se o site avaria num ponto e o resto funciona, a causa está no código, num plugin ou no tema.
Os bots podem deitar abaixo um site WordPress num alojamento barato
Podem. Um bot que percorre endereços sem cache arranca o PHP a cada pedido. Num alojamento partilhado com poucos workers PHP, a fila enche depressa e os pedidos seguintes terminam com o erro 504, descrito nas secções abaixo. Ajudam a cache de páginas à frente do PHP (no servidor ou numa CDN) e um limite de pedidos por cliente. Ao bloquear bots no Cloudflare, tenha cuidado com a opção que também corta o acesso ao Googlebot, como explicámos no artigo o Cloudflare bloqueia o Googlebot.
As atualizações de plugins estragam o site WordPress
Um dos participantes no tópico aponta as atualizações de plugins como causa frequente de falhas quando são aplicadas diretamente no site em produção, sem teste num ambiente de staging (tradução própria, technomalist, r/webdev). Se as falhas coincidem com atualizações, compare as datas das falhas com o histórico de atualizações. A forma de trabalhar com uma cópia de teste está no nosso guia de staging para WordPress.
Falhas repetidas podem significar que o site foi pirateado
Podem. No tópico surge a descrição de um ciclo típico: um site infetado através de um plugin vulnerável é reposto a partir de uma cópia de segurança, mas a falha de segurança continua aberta, e passados alguns dias tudo se repete (tradução própria, 30thnight, r/webdev). Repor a cópia sem eliminar a causa não resolve o problema. Os passos da limpeza estão no guia para remover malware do WordPress.
Como saber porque é que o site WordPress foi abaixo
A resposta mais curta do tópico é: “O que dizem os logs?” (tradução própria, chmod777, r/webdev). O dono do site consegue fazê-lo sem programador:
- Ative uma monitorização externa da disponibilidade que registe a hora e a duração de cada falha.
- Tenha o seu próprio acesso ao painel do alojamento, e não apenas ao painel do WordPress.
- Depois de uma falha, abra o registo de erros do PHP e o registo de erros do servidor web da mesma hora. Erros fatais do PHP apontam para o código ou para um plugin; limites de processos ultrapassados e timeouts apontam para os recursos do alojamento.
- Compare as horas das falhas com as datas das atualizações de plugins, do tema e do WordPress.
Vale a pena pagar um plano de manutenção para WordPress
Um plano de manutenção paga trabalho regular: atualizações testadas antes de irem para produção, monitorização, cópias de segurança e resposta às falhas. Não deve, no entanto, ser a resposta a falhas cuja causa ninguém identificou. Uma falha de poucas em poucas semanas não é normal, com ou sem plano. Depois de cada falha, deve receber por escrito a causa e o que foi alterado para que não se repita. É assim que trabalhamos na manutenção de sites WordPress.
Como verificar onde o pedido ficou preso
Comece por três sítios, por esta ordem.
- Registo de erros do servidor web da hora da falha. No nginx, uma entrada
upstream timed outconfirma que o servidor ficou à espera do PHP. - Registo do PHP-FPM. A mensagem de que o
pm.max_childrenfoi atingido significa que o pool estava cheio e os pedidos seguintes ficaram em fila. A opçãopm.max_children, como descreve a documentação do PHP, define o limite de pedidos simultâneos servidos pelo pool. - Registo do WordPress. No
wp-config.php, definaWP_DEBUGcomotrue,WP_DEBUG_LOGcomotrueeWP_DEBUG_DISPLAYcomofalse. Os erros vão parawp-content/debug.logem vez de aparecerem no ecrã. É assim que a documentação do WordPress o descreve. Desative o debug depois do diagnóstico.
Quando o alojamento dá acesso ao slowlog do PHP-FPM, defina request_slowlog_timeout e o PHP regista o backtrace dos pedidos que demoram mais do que o limite. Por predefinição a opção está desativada (valor 0). O backtrace mostra em que função do plugin ou do tema o PHP ficou à espera.
Num alojamento partilhado, muitas vezes não há acesso a estes registos. Nesse caso, o acesso a eles e às métricas do pool PHP é a primeira coisa a pedir ao suporte, juntamente com a hora da falha e o endereço que devolveu o 504.
Porque é que um pool PHP-FPM demasiado pequeno dá 504
Cada pedido dinâmico ocupa um worker do PHP-FPM até ao fim da resposta. Quando todos os workers estão ocupados, os novos pedidos esperam. Se esperarem mais do que o limite do proxy, o visitante vê um 504.
O fastcgi_read_timeout predefinido no nginx é de 60 segundos e a documentação do nginx assinala que o limite é contado entre duas leituras consecutivas do servidor FastCGI, não para a resposta inteira. Em alojamentos geridos o valor pode ser outro, por isso não parta do princípio de que no seu caso são precisamente 60 segundos.
Aumentar o pm.max_children só ajuda se o servidor tiver memória para isso. Cada worker de um WordPress com alguns plugins ocupa uma fatia considerável, pelo que um valor demasiado alto acaba em esgotamento de RAM e processos terminados à força, ou seja, um estado pior do que a fila. A configuração do pool é tarefa para o administrador, que vê o consumo de memória.
Como é que consultas lentas e opções com carregamento automático causam 504
Quando o 504 afeta o site inteiro e o pool não está cheio por causa do tráfego, verifique a base de dados. A documentação do WordPress chama a atenção para o facto de o WordPress repetir muitas consultas a cada pedido e de as opções marcadas como autoload serem carregadas em cada visita. Recomenda mantê-las abaixo de 800 KB, e as recomendações completas estão descritas no guia de otimização. Um plugin que grava dados volumosos em wp_options com autoload empurra-os para cada pedido. O tamanho do autoload verifica-se com uma consulta SQL pela coluna autoload na tabela de opções.
Para identificar consultas lentas serve a constante SAVEQUERIES. Regista cada consulta, o tempo de execução e a função que a chamou em $wpdb->queries. Tem custo de desempenho, por isso ative-a por pouco tempo e, se possível, num ambiente de staging.
Quando é que a cache de objetos e o Redis causam 504
Uma cache de objetos persistente reduz o número de consultas à base de dados e normalmente acelera o site. Exige, no entanto, um servidor de cache a funcionar e o ficheiro drop-in wp-content/object-cache.php.
A falha funciona no sentido inverso quando esse ficheiro existe e o servidor Redis não responde. Cada pedido tenta então ligar-se à cache, espera pelo timeout da ligação e só depois segue em frente ou desiste. O sintoma é um 504 logo após um reinício ou uma falha do serviço de cache no alojamento, apesar de o código do site não ter mudado.
O teste é simples: mude o nome do object-cache.php para outro. Se o 504 desaparecer, a culpa é da cache e não do WordPress. Reponha o ficheiro apenas depois de reparar o serviço.
Como é que o WP-Cron, o admin-ajax e as APIs externas provocam 504
Convém verificar em separado três origens de pedidos lentos isolados.
- WP-Cron. A documentação do WordPress explica que o WP-Cron é executado quando alguém visita o site, não como processo permanente. Tarefas pesadas em atraso (cópias de segurança, importações, envios) podem assim sobrecarregar o pedido normal de um visitante. Passar as chamadas para o cron do sistema do alojamento alivia o front-end.
- admin-ajax.php. Os plugins enviam aqui pedidos do painel e do front-end. Se o 504 surgir precisamente aqui, procure o plugin que faz uma operação pesada em segundo plano.
- APIs externas. Um plugin que espera por um sistema externo lento (pagamentos, ERP, expedição) segura o worker enquanto o outro sistema demorar a responder. A falta de um timeout curto e próprio nesse plugin transforma a falha de terceiros no seu 504.
Em que difere o 504 do 502 e do 524
- 502 Bad Gateway: o servidor atrás do proxy respondeu, mas a resposta era inválida. Muitas vezes é um processo PHP-FPM que caiu.
- 504 Gateway Timeout: sem resposta a tempo. Na maioria dos casos, sobrecarga ou um pedido lento.
- 524: código da Cloudflare. A documentação da Cloudflare indica que surge quando o servidor de origem não responde nos 125 segundos predefinidos. A Cloudflare aconselha a pedir ao alojamento que verifique processos longos e sobrecarga, e a mover as operações grandes para um canal sem proxy.
Atrás de uma CDN pode, portanto, ver dois códigos diferentes para a mesma causa, consoante o elo que perdeu primeiro a paciência.
Quando aumentar o timeout e quando não
Aumentar o fastcgi_read_timeout ou o limite de tempo do PHP justifica-se para uma única operação deliberadamente longa, por exemplo uma importação manual. Para um site que mostra 504 aos visitantes, é mascarar o problema: o pedido lento continua a ocupar o worker, só que durante mais tempo, e o pool enche-se mais depressa.
O PHP-FPM tem outro mecanismo de segurança, o request_terminate_timeout. A documentação descreve-o como o limite a partir do qual o processo que serve o pedido é terminado e indica o valor predefinido 0, ou seja, desativado. Definido com bom senso, protege o pool de um único script bloqueado.
Atualização de . Tarefas longas no wp-admin, como uma cópia de segurança ou uma exportação da base de dados, são uma causa clássica de 504 em alojamento partilhado. Nesse tipo de plano raramente é possível alterar o limite do proxy, e o proxy fecha o pedido antes de o PHP terminar, seja qual for o valor de max_execution_time. A solução é dividir a tarefa em pedidos curtos que possam ser retomados. O nosso plugin Migrator ilustra o padrão. Desde a versão 1.6.0, uma cópia de segurança iniciada no wp-admin exporta a base de dados por etapas, um lote de linhas por pedido, pelo que uma base de dados grande é exportada sem um 504 Gateway Timeout em alojamento partilhado. Uma etapa interrompida retoma onde a anterior parou, e o filtro migrator_step_seconds define quanto tempo cada etapa pode trabalhar, para alojamentos cujo proxy corta os pedidos mais cedo. Se a exportação ou importação de um plugin falha com 504 sempre num ponto semelhante, procure um modo que trabalhe por lotes e possa ser retomado, ou comandos WP-CLI (o Migrator tem comandos wp migrator desde a versão 1.5.0). Subir os limites do PHP não resolve, porque o proxy ignora-os.
Que timeouts do nginx acabam num erro 504
O módulo FastCGI do nginx tem três temporizadores separados e, segundo a documentação do ngx_http_fastcgi_module, cada um tem 60 segundos por predefinição.
| Diretiva | O que mede | Predefinição |
|---|---|---|
fastcgi_connect_timeout | o estabelecimento da ligação ao PHP-FPM | 60 s, normalmente não mais de 75 s |
fastcgi_send_timeout | o intervalo entre duas escritas consecutivas do pedido para o PHP-FPM | 60 s |
fastcgi_read_timeout | o intervalo entre duas leituras consecutivas da resposta | 60 s |
Os dois últimos temporizadores recomeçam a cada bloco de dados. Um script que envia algo de vez em quando pode, por isso, trabalhar mais de um minuto sem erro. Um script que fica em silêncio porque espera pela base de dados ou por uma API externa recebe um 504 aos 60 segundos. O fastcgi_send_timeout pesa sobretudo em pedidos POST grandes, como o carregamento de um ficheiro ou uma importação.
Quando o nginx está à frente do Apache e não diretamente à frente do PHP-FPM, o que conta é o proxy_read_timeout do módulo ngx_http_proxy_module. Também tem 60 segundos e também mede o intervalo entre leituras, não a resposta inteira.
Todas estas diretivas funcionam nos contextos http, server e location. É possível, portanto, aumentar o limite apenas para o caminho que realmente precisa dele, em vez de o fazer para o servidor inteiro:
location = /wp-admin/admin-ajax.php {
# limite maior apenas aqui, o resto do servidor fica nos 60 s
fastcgi_read_timeout 120s;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_pass unix:/run/php/php-fpm.sock;
}O caminho para o socket do PHP-FPM varia entre distribuições e alojamentos, por isso copie-o da sua configuração atual e não do exemplo.
Timeout no Apache com PHP-FPM e mod_proxy_fcgi
O Apache passa o PHP ao PHP-FPM através do mod_proxy_fcgi, normalmente com SetHandler "proxy:unix:/caminho/para/socket.sock|fcgi://localhost/". O tempo de espera é definido aqui por três configurações, cada uma herdando o valor predefinido da seguinte:
Timeout, do núcleo do Apache, com 60 segundos por predefinição. A documentação do Apache indica que é este o valor predefinido nomod_proxyquando oProxyTimeoutnão está definido.ProxyTimeout, do mod_proxy, igual aoTimeoutpor predefinição. A documentação descreve-o como forma de devolver um erro de timeout quando um servidor de aplicação bloqueia, em vez de esperar o tempo que for preciso.- o parâmetro
timeoutnoProxyPassou na definição de um worker, igual aoProxyTimeoutpor predefinição. Indica quantos segundos o Apache espera por dados enviados para o backend ou recebidos dele.
As três têm o contexto server config e virtual host, pelo que não funcionam no .htaccess. Num alojamento partilhado, só o administrador do servidor as pode alterar.
Porque é que o max_execution_time não protege contra o 504
O max_execution_time do PHP tem 30 segundos por predefinição, menos do que os 60 segundos do nginx. Parece, então, que o PHP termina sempre o script antes de o proxy devolver um 504. Não é assim. A documentação do PHP indica que, em sistemas que não sejam Windows, as chamadas ao sistema e as operações sobre streams não contam para este limite, e a página de set_time_limit() acrescenta que o tempo gasto em consultas à base de dados também não é contado.
Na prática, um pedido do WordPress que espera 70 segundos por uma tabela MySQL bloqueada ou por um gateway de pagamentos nunca atinge o limite do PHP. O worker continua ocupado e o nginx devolve um 504 após 60 segundos de silêncio. A exceção são as compilações do PHP com --enable-zend-max-execution-timers (predefinida nas compilações ZTS desde o PHP 8.3.0), em que o limite mede o tempo decorrido, incluindo a espera por entrada e saída.
Por isso, com APIs externas, o que conta é o timeout da própria ligação. As funções HTTP do WordPress (WP_Http::request) têm um timeout predefinido de 5 segundos, ajustável com o filtro http_request_timeout. Um plugin que sobe este valor para um minuto retira essa proteção, e é esse plugin que transforma uma API lenta num 504.
Destes números resulta uma ordem que facilita o diagnóstico: cada limite interior mais curto do que o exterior. O timeout HTTP do plugin (5 s) abaixo do limite do PHP (30 s), este abaixo do fastcgi_read_timeout (60 s) e este abaixo dos 125 segundos da Cloudflare. Quando o limite interior dispara primeiro, o erro fica registado no debug.log com o nome da função que estava à espera. Quando dispara primeiro o exterior, resta apenas uma página 504 genérica, sem rasto nos registos do WordPress.
Como ler a página de estado do PHP-FPM
A prova mais rápida de que um 504 vem de uma fila ou de um único pedido lento é a página de estado do PHP-FPM. Ativa-se com a opção pm.status_path na configuração do pool, que por predefinição não está definida. A documentação do PHP avisa que a página revela os endereços dos pedidos e informação sobre os recursos, pelo que deve ficar restrita a pedidos internos ou a endereços IP conhecidos. O parâmetro ?json devolve JSON e o ?full acrescenta detalhes de cada processo.
| Campo | O que significa |
|---|---|
listen queue | pedidos que neste momento esperam por um processo livre |
max listen queue | a maior fila desde o arranque do pool |
active processes / idle processes | processos ocupados e livres |
max children reached | 1 ou mais se o pool alguma vez atingiu o pm.max_children |
slow requests | pedidos que ultrapassaram o request_slowlog_timeout |
A leitura durante uma falha é simples. Uma fila acima de zero e nenhum processo livre significam um pool cheio: workers a menos ou pedidos lentos que os prendem. Uma fila vazia e processos livres ao mesmo tempo que um 504 significam que o tempo se perde dentro do próprio pedido, ou seja, na base de dados, na cache ou numa API externa. O limite superior da fila é definido pelo listen.backlog, de 511 por predefinição em Linux, segundo a referência de configuração do FPM.
Como corrigir o 504 passo a passo
- Determine o âmbito: site inteiro, um endereço ou apenas o wp-admin.
- Leia os registos do servidor e do PHP-FPM da hora da falha.
- Ative o
debug.loge reproduza o erro. - Desative os plugins (via WP-CLI ou mudando o nome da pasta), depois ative-os um a um e meça o tempo de resposta.
- Se existir o
object-cache.php, desative-o como teste. - Verifique as opções com carregamento automático e as tarefas do WP-Cron em atraso.
- Só no fim considere aumentar o pool ou os timeouts, em conjunto com o administrador do alojamento.
Se o 504 apareceu logo a seguir a uma atualização, consulte também o guia sobre como recuperar o WordPress após uma atualização falhada.
Quando é trabalho para um especialista
Quando os registos apontam para o pool PHP-FPM, mas o alojamento não dá acesso à sua configuração. Quando o 504 volta depois de cada correção. Quando a loja perde encomendas durante a falha. Numa auditoria que deve separar o custo do alojamento do custo do código, ajuda a otimização do desempenho de um site WordPress. Quando o site está em baixo neste momento e a causa é desconhecida, a salvação é a reparação e o suporte técnico WordPress.






