PHP
14 min de leitura

PHP-FPM em APIs em produção: erros que geram falhas, lentidão ou retrabalho

Erros 502, 504 e lentidão nem sempre indicam falta de workers. Entenda como medir memória, localizar filas, alinhar timeouts e validar ajustes do PHP-FPM em APIs de produção.

M

Max Alex

PHP-FPM em APIs em produção: erros que geram falhas, lentidão ou retrabalho
Neste artigo (10 tópicos)

Como identificar gargalos, dimensionar workers e alinhar configurações para manter sua API estável sob carga.

A API começa a responder devagar, surgem erros intermitentes e alguém aumenta o número de processos PHP. Por alguns minutos, o atendimento melhora. Depois, o consumo de memória cresce, o banco recebe mais conexões e o problema volta com outra aparência.

Operar PHP-FPM em produção exige relacionar capacidade, duração das requisições e limites das dependências. Ajustar o pool sem essas evidências pode transformar uma espera por serviço externo em falta de memória.

Este roteiro apresenta oito erros frequentes, os sinais que ajudam a diferenciá-los e uma sequência de validação para reduzir falhas, lentidão e retrabalho.

Como o PHP-FPM atende uma API e onde surgem as filas

Em uma instalação comum, a requisição passa pelo proxy ou balanceador, chega ao Nginx e segue por FastCGI até o PHP-FPM. A comunicação pode usar um socket Unix ou um endereço TCP. No pool, um worker executa o código PHP e devolve a resposta.

Cada worker atende uma requisição por vez. Enquanto aguarda uma consulta ao banco ou uma resposta HTTP externa, esse processo continua ocupado. CPU moderada, portanto, não significa que exista capacidade disponível para atender novas chamadas.

Quando todos os workers estão ocupados, novas requisições podem aguardar na fila de escuta antes de executar PHP. Também podem existir esperas em outras camadas. Por isso, o tempo percebido pelo cliente inclui mais do que a execução registrada pela aplicação.

Exemplo hipotético: um pool tem 12 workers, todos esperando um fornecedor responder. Uma nova chamada a um endpoint simples precisa aguardar, embora esse endpoint normalmente execute em poucos milissegundos. A dependência lenta passa a afetar rotas que nem utilizam o fornecedor.

Observe p95 e p99 por endpoint: eles mostram limites de duração abaixo dos quais ficam, respectivamente, 95% e 99% das requisições observadas. Uma média aceitável pode coexistir com uma parcela de chamadas muito lentas.

Para revisar essa arquitetura, o guia de implementação aprofunda a integração entre Nginx e FastCGI. Com o caminho da requisição definido, fica mais fácil separar espera por capacidade de execução lenta.

Erro 1: dimensionar pm.max_children sem medir memória e concorrência

O pm.max_children estabelece o limite de atendimento simultâneo do pool. Um valor pequeno pode criar filas; um valor excessivo pode esgotar memória ou ampliar a disputa por CPU e conexões de banco.

Comece pelo orçamento real da instância. Reserve recursos para sistema operacional, servidor web, agentes, outros serviços e estruturas compartilhadas. Se houver vários pools, considere o consumo combinado.

Uma estimativa inicial baseada em memória

Em um cenário ilustrativo, restam 1.200 MiB para os processos do pool, depois das reservas. Se o consumo estimado por worker sob carga representativa for de 80 MiB, a divisão resulta em 15 workers. Esse número é uma hipótese inicial, antes de incorporar margem para variações.

Estimativa inicial = orçamento do pool / consumo estimado por worker
1.200 MiB / 80 MiB = 15 workers

Meça endpoints leves e pesados, uploads, respostas volumosas e processos que já atenderam muitas requisições. RSS contabiliza páginas residentes, mas sua soma pode contar memória compartilhada repetidamente. PSS distribui esse compartilhamento proporcionalmente e ajuda a interpretar o consumo. Nenhuma amostra isolada substitui acompanhar a memória total da instância sob carga.

PHP-FPM consumo de memória: o memory_limit do PHP não representa o consumo total de um processo. Usá-lo como único dado para dimensionar o pool ignora componentes que precisam aparecer na medição operacional.

Verifique os limites além da RAM

O dimensionamento de workers PHP também depende de CPU e das dependências. Se cada processo puder manter conexões ao banco, elevar o pool em várias réplicas pode ultrapassar a capacidade de conexão ou processamento do banco.

Em contêineres, use os limites efetivos de memória e CPU. A RAM disponível no host não é necessariamente utilizável pela aplicação. Procure eventos de OOM, reinicializações e throttling, quando a execução fica limitada pela cota de CPU.

Valide o candidato com carga representativa. Se a fila cair, mas a latência do banco subir e a taxa de sucesso piorar, o aumento de workers apenas deslocou o gargalo.

Erro 2: escolher o modo do pool sem considerar o padrão de tráfego

Os modos static, dynamic e ondemand definem como os processos são mantidos. A escolha deve considerar memória disponível, períodos ociosos e velocidade das rajadas.

Modos de gerenciamento do pool
ModoFuncionamentoO que validar
staticMantém uma quantidade fixa de processos.Memória ocupada durante períodos de baixo tráfego.
dynamicAjusta a quantidade de processos dentro dos limites configurados.Disponibilidade de processos ociosos quando chegam rajadas.
ondemandCria processos conforme chegam requisições.Latência de criação após períodos sem acessos.

No modo dynamic, pm.start_servers define os processos iniciais; pm.min_spare_servers e pm.max_spare_servers controlam a faixa desejada de processos ociosos. Já pm.process_idle_timeout se aplica ao ondemand.

Uma API com tráfego constante pode se beneficiar de processos já disponíveis. Outra, acessada poucas vezes ao dia, pode economizar memória com criação sob demanda. Essas são hipóteses para teste: medir a primeira chamada após ociosidade e a resposta a uma rajada ajuda a decidir.

Ao avaliar alternativas de execução, o artigo sobre erros no Laravel Octane em APIs de alto tráfego oferece um contexto relacionado. Os modelos de execução exigem cuidados próprios; não transfira parâmetros entre eles automaticamente.

Erro 3: tratar todo 502 ou 504 como falta de workers

O código HTTP mostra o resultado observado em uma camada da cadeia. Ele não identifica sozinho a causa. No diagnóstico de erro 502 PHP-FPM ou erro 504 PHP-FPM, localize primeiro qual componente gerou a resposta.

Hipóteses para investigar falhas no atendimento
SinalPossível causaEvidência a verificar
502 com falha de conexãoServiço parado, endereço incorreto ou socket inacessível.Log do Nginx, estado do FPM e correspondência entre os endereços.
502 com encerramento inesperado do upstreamWorker encerrado, falha de processo ou interrupção durante implantação.Logs do FPM, eventos de OOM e reinicializações.
504 com timeout do upstreamEspera por atendimento, execução lenta ou dependência demorando.Fila, ocupação do pool, traces e duração das dependências.
Latência crescente com pool ocupadoSaturação de capacidade ou aumento da duração das chamadas.Workers ativos, fila, CPU e tempos por endpoint.

Correlacione horário, instância, endpoint e identificador de requisição entre proxy, Nginx e aplicação. Confira também se os relógios estão sincronizados, para evitar conclusões baseadas em eventos aparentemente fora de ordem.

Um 502 logo após alterar o caminho do socket pede a comparação entre listen e fastcgi_pass. Verifique existência do socket, permissões de acesso do servidor web e eventuais políticas de segurança. Em TCP, confira endereço, porta, conectividade e clientes autorizados.

Um 504 acompanhado de consulta lenta exige outra investigação: plano de execução, bloqueios, transações e ocupação dos workers. Aumentar o pool não corrige um endereço errado e pode agravar um banco saturado.

Erro 4: configurar timeouts isoladamente e multiplicar tentativas

A configuração do PHP-FPM precisa participar de um orçamento de tempo que inclua cliente, gateway, aplicação e dependências. Valores ajustados isoladamente podem encerrar a espera externa enquanto o servidor continua trabalhando.

Separe timeout de conexão, espera por dados e duração total. No Nginx, fastcgi_read_timeout limita o intervalo entre leituras sucessivas do upstream; não estabelece um prazo total universal para a resposta.

max_execution_time e request_terminate_timeout também têm funções diferentes. Em sistemas não Windows, o primeiro não contabiliza diversas esperas externas como um cronômetro de tempo total. O segundo pode encerrar o worker ao exceder o limite de atendimento configurado.

Como hipótese de projeto, uma operação com prazo externo de cinco segundos poderia reservar até dois segundos para uma dependência e manter tempo para processamento e resposta. Verifique a semântica do cliente HTTP: um timeout de leitura pode ter comportamento diferente de um limite total.

Exemplo: o gateway desiste da resposta, mas a chamada ao fornecedor continua bloqueada. O worker permanece ocupado, e a retentativa do cliente adiciona outra requisição. Revise limites internos e teste o comportamento de desconexão; o fim da espera do cliente não garante cancelamento imediato no servidor ou no fornecedor.

Retentativas também consomem capacidade

Defina quais falhas são transitórias, limite o número de tentativas e use backoff com variação aleatória para evitar repetições simultâneas. Inclua essas tentativas no orçamento total.

Operações que criam cobranças, pedidos ou outros efeitos precisam de proteção contra duplicidade. Antes de repetir, considere idempotência, persistência do resultado e a possibilidade de a primeira tentativa ter concluído mesmo sem resposta ao cliente.

Teste também o que acontece quando um limite encerra o processo durante uma operação. Retornar timeout não prova que todos os efeitos foram desfeitos.

Erro 5: aumentar o pool para compensar banco lento e tarefas demoradas

A duração das requisições determina por quanto tempo cada worker fica indisponível. Consultas N+1, índices inadequados, bloqueios e transações longas podem consumir a capacidade do pool sem exigir muita CPU do servidor PHP.

Antes de ampliar processos, identifique os endpoints que mais ocupam tempo e os trechos responsáveis pela espera. Compare traces da aplicação com consultas lentas e métricas de bloqueio do banco. Para integrações externas, observe duração, falhas e tentativas por chamada.

Mais workers podem gerar mais consultas concorrentes. Se o banco já estiver saturado, essa mudança pode aumentar o tempo de execução de todas elas. Avalie otimizações e cache com dados de antes e depois, considerando validade e invalidação dos resultados armazenados.

Quando retirar o trabalho da resposta síncrona

Um endpoint que produz relatórios grandes pode ocupar workers por vários segundos. Se o usuário não precisa receber o arquivo imediatamente, considere persistir uma tarefa e responder com HTTP 202 Accepted, incluindo um identificador para consulta posterior.

A resposta 202 indica aceitação, sem garantir conclusão. O processamento exige persistência confiável, controle de duplicidade, retentativas limitadas e estados consultáveis, como pendente, em execução, concluído ou falhou.

Esse desenho permite dimensionar o processamento de relatórios separadamente do atendimento HTTP. Ainda será necessário monitorar idade das tarefas, falhas e capacidade dos consumidores.

Finalizar a resposta com fastcgi_finish_request() e continuar executando código no mesmo processo não libera automaticamente o worker para outra requisição. Para tarefas duráveis e demoradas, avalie uma fila com consumidores próprios.

Erro 6: operar sem status do pool, slowlog e métricas de saturação

Sem observabilidade, ajustes viram tentativas difíceis de comparar. O status do pool ajuda a acompanhar processos ativos e ociosos, fila de escuta e ocorrências em que o limite de processos foi alcançado.

Alguns indicadores são acumulados desde o início do pool. Analise sua evolução no intervalo do incidente e considere reinicializações; um total histórico, sozinho, não comprova saturação atual.

Para investigar execução lenta, configure PHP-FPM slowlog com um limiar adequado à API. O trecho abaixo é apenas um exemplo parcial; o caminho precisa existir e permitir escrita, e a instalação deve permitir a coleta do backtrace.

; Exemplo parcial: ajuste à instalação
request_slowlog_timeout = 2s
slowlog = /var/log/php-fpm/api-slow.log

O slowlog registra uma pilha de execução após o limiar. Ele ajuda a localizar onde um worker estava, mas não mede toda a espera anterior ao atendimento nem substitui traces distribuídos.

  • Compare fila e ocupação do pool com p95, p99 e taxa de erros por endpoint.
  • Acompanhe CPU, memória, throttling, encerramentos e reinicializações.
  • Relacione os sinais com conexões, bloqueios e latência do banco.
  • Use identificadores de requisição para conectar logs e traces.

Considere esta sequência: p99 sobe, a fila cresce e os workers permanecem ocupados; amostras do slowlog apontam espera na mesma integração externa. A hipótese passa a ser demora nessa dependência, a confirmar pelos traces e tempos do cliente HTTP.

Restrinja status e diagnóstico a acessos autorizados. Quando houver suporte na versão instalada, pm.status_listen permite consultar o status por um listener separado, útil quando o atendimento principal está saturado.

Erro 7: usar reciclagem de workers e OPcache sem uma estratégia

pm.max_requests permite substituir workers após determinada quantidade de requisições. Essa reciclagem pode conter efeitos de crescimento de memória, mas não elimina a necessidade de investigar sua origem.

Valores muito baixos aumentam a frequência de substituição de processos. Compare memória, latência e criação de workers antes de definir uma política. Observe se o crescimento acompanha endpoints específicos, extensões ou bibliotecas.

O OPcache também precisa de acompanhamento: utilização de memória, capacidade para scripts e reinicializações ajudam a avaliar se ele está operando como esperado.

Se opcache.validate_timestamps estiver desabilitado, alterações nos arquivos exigem uma estratégia explícita de atualização do cache ou dos processos. O procedimento deve alcançar todas as instâncias que continuam recebendo tráfego.

Executar opcache_reset() no PHP da linha de comando não garante atualização do cache utilizado pelo PHP-FPM. Verifique o ambiente de execução e confirme a versão efetivamente atendida por cada instância.

Exemplo: após uma implantação, parte das respostas mantém o comportamento antigo. Investigue instâncias ainda executando a versão anterior e a estratégia do OPcache antes de atribuir o problema ao balanceamento.

Erro 8: implantar mudanças sem validar configuração e drenar requisições

Um arquivo editado corretamente pode não ser o arquivo carregado pelo serviço. Confira includes, configurações geradas, overrides do pool, volumes montados e diferenças entre ambientes.

Use o binário correspondente à instalação para validar a configuração. Estes comandos são exemplos comuns; nome do executável, permissões e caminho dos arquivos podem variar.

php-fpm -t
nginx -t

Se o serviço usa um arquivo específico, valide esse mesmo arquivo. A configuração do PHP CLI também pode diferir da utilizada pelo FPM, então uma verificação feita apenas na linha de comando não descreve necessariamente o atendimento HTTP.

Aplique a mudança com critérios observáveis

  1. Registre valores atuais e resultados de referência.
  2. Valide a configuração candidata e o procedimento de reversão.
  3. Retire uma instância do tráfego e permita a conclusão das chamadas em andamento.
  4. Aplique a mudança conforme o comportamento documentado do serviço.
  5. Verifique prontidão e comportamento sob tráfego antes de ampliar a implantação.

Confirme o significado de reload e restart no gerenciador utilizado. O tempo de encerramento precisa considerar requisições em andamento; em contêineres, o prazo de término também pode interromper o processo.

Processo ativo não significa aplicação pronta. Uma verificação de prontidão deve demonstrar que a instância consegue atender seu fluxo essencial, sem criar carga excessiva nas dependências.

Por exemplo, aplique um novo limite de workers em uma instância e compare erros, p99, fila e memória. Amplie somente após observar o resultado durante um período representativo. Defina antecipadamente em quais condições a mudança será revertida.

Checklist para diagnosticar e ajustar o PHP-FPM com segurança

Use esta sequência durante incidentes e revisões preventivas. O objetivo é conectar uma alteração a uma hipótese verificável, com evidências suficientes para decidir se ela deve permanecer.

  1. Delimite o sintoma: registre endpoints, horários, volume de chamadas, códigos HTTP, instâncias e alterações recentes.
  2. Verifique disponibilidade: examine logs, estado do FPM, comunicação FastCGI, recursos e reinicializações.
  3. Localize a espera: compare fila, workers ocupados, latência por endpoint e duração das dependências.
  4. Defina uma hipótese: explique qual evidência sustenta a causa proposta e o resultado esperado.
  5. Controle a mudança: altere um conjunto pequeno e coerente de parâmetros.
  6. Teste situações relevantes: inclua mistura de endpoints, rajadas, períodos ociosos e dependências lentas.
  7. Compare e documente: registre configuração, resultado, limitações e critérios de reversão.

Ficha prática de diagnóstico

Sintomap99 aumenta no horário de maior tráfego e surgem respostas 504.EvidênciaFila crescente, pool ocupado e traces mostrando espera predominante no fornecedor.HipóteseA demora da integração prolonga a ocupação dos workers.Ajuste propostoRevisar limites da chamada externa e reduzir tentativas dentro do orçamento da operação.Resultado esperadoMenor ocupação prolongada e menos chamadas prejudicadas por essa dependência.ValidaçãoComparar p99, fila, taxa de sucesso e erros da integração sob carga equivalente.Condição de reversãoReverter se operações necessárias falharem acima do limite acordado ou se o comportamento global piorar.

Conte respostas úteis, não apenas redução de latência: rejeitar chamadas mais rapidamente pode melhorar um percentil sem melhorar o serviço. Da mesma forma, ampliar a fila de escuta acomoda espera, mas não aumenta a capacidade de execução.

Não existe uma configuração universal de PHP-FPM em APIs. O limite adequado depende da aplicação, dos recursos disponíveis, do perfil de tráfego e da capacidade das dependências.

Aplique o checklist à sua API e registre as evidências antes de alterar o pool. Para aprofundar o diagnóstico, explore os conteúdos relacionados sobre PHP, desempenho e operação de APIs no blog Max Alex.

M
Publicado por

Max Alex

Desenvolvedor full stack especializado em SaaS, Laravel, IA aplicada, WhatsApp API, automações e integrações. Criação de sistemas web escaláveis para empresas.

Conhecer Max Alex
Próximas leituras

Continue lendo

Ver todos os artigos →