'server reached pm.max_children' na loja virtual: como dimensionar os processos PHP-FPM pela memória da VPS antes de concluir que falta servidor
Aprenda a calcular o pm.max_children certo para sua VPS. Meça o consumo de cada processo PHP-FPM, desconte banco e cache, e evite fila com a máquina ociosa.
2026-09-23 · Equipe · 10 min de leitura
A linha ‘server reached pm.max_children’ no log quer dizer que todos os processos PHP da loja estão ocupados e os próximos clientes estão na fila. Antes de comprar servidor, faça a conta de quantos processos cabem na memória da VPS: meça quanto cada um consome, desconte banco, cache e sistema, e divida o que sobra.
Quando o log do PHP-FPM mostra ‘server reached pm.max_children’, a loja não ficou necessariamente sem servidor: ficou sem processo livre para executar o PHP. Antes de trocar de máquina, confira se o limite foi calculado pela memória da VPS: meça o consumo de cada processo, desconte banco, cache e sistema, e divida o que sobra.
- ‘server reached pm.max_children’ significa que todos os processos PHP-FPM estão ocupados. As próximas requisições esperam na fila e, se a espera fica longa, o visitante recebe 502 ou 504.
- O limite certo é a memória que sobra depois de sistema, banco e cache, dividida pelo consumo real de cada processo.
- Limite baixo trava a loja com a máquina ociosa. Limite alto leva ao swap e ao OOM killer, queda pior que a fila.
- Se o processo está parado esperando frete, gateway ou banco, subir o limite não resolve.
- Se o limite já está calculado e a memória acabou, falta máquina. Aí entra o burst: cada servidor extra chega com a própria cota de processos.
Loja parada com a CPU tranquila e ‘server reached pm.max_children’ no log
No pico, a loja trava ou devolve 502 e 504, a CPU está folgada e o log do PHP-FPM registra WARNING: [pool www] server reached pm.max_children setting. O PHP-FPM chegou ao teto de processos e todos estão ocupados: acabou atendente livre, não processador.
Onde fica o log: no Debian e no Ubuntu, /var/log/php8.2-fpm.log (troque 8.2 pela sua versão); na família Red Hat, /var/log/php-fpm/error.log; em contêiner, docker logs.
Para contar as ocorrências por dia e hora: grep max_children /var/log/php8.2-fpm.log | cut -c2-15 | sort | uniq -c. Se elas se concentram no horário de campanha, o limite trava a loja quando ela mais vende. Os códigos de erro estão em o que 502, 503 e 504 significam.
PHP-FPM como fila de atendentes: pm.max_children, pm e pm.max_requests
O PHP-FPM (FastCGI Process Manager) mantém processos prontos para executar o PHP da loja, seja WooCommerce, Magento ou outra plataforma. O nginx ou o Apache repassa cada visita a um desses processos, que atende uma requisição por vez, como um guichê com um atendente só.
pm.max_children: o máximo de atendentes simultâneos. Com todos ocupados, a requisição espera na fila até virar 504 (tempo do nginx esgotado) ou 502 (fila transbordada).pm(process manager): a regra que decide quando abrir e fechar processos.pm.max_requests: quantas requisições um processo atende antes de ser reciclado. Protege contra plugin com vazamento de memória.
static, dynamic e ondemand
- static mantém sempre o máximo de processos abertos. Serve para VPS dedicada à loja.
- dynamic mantém uma faixa entre mínimo e máximo, ajustada por
pm.start_servers,pm.min_spare_serversepm.max_spare_servers. - ondemand abre processo quando chega requisição e o fecha após um tempo parado. Serve para pouco tráfego ou vários sites na mesma máquina.
Os três obedecem ao mesmo teto, pm.max_children: trocar de modo muda quando os processos abrem, não a capacidade.
Como medir a memória real de cada processo PHP-FPM com ps e smem
Meça com a loja em movimento, no pico ou num teste de carga. Processo ocioso consome menos e distorce a conta.
ps -eo pid,rss,cmd | grep '[p]hp-fpm: pool' lista os processos que atendem cliente, sem o mestre e sem a linha do grep. RSS é a memória física ocupada, em kilobytes.
Média em megabytes: ps -eo rss,cmd | grep '[p]hp-fpm: pool' | awk '{s+=$1; n++} END {print s/n/1024}'. O RSS superestima o consumo, porque a memória compartilhada (o código do PHP e o OPcache, que guarda o código já compilado) aparece repetida em cada processo.
O smem mostra a coluna PSS, que divide a memória compartilhada entre os processos e é mais fiel. Não vem instalado: no Debian e no Ubuntu, apt install smem; depois, smem -k -t -P '^php-fpm: pool'.
Use a média com margem para os processos pesados: admin, importação e relatório gastam mais que página de produto. Em contêiner, docker stats mostra o total; dividido pelo número de processos, dá uma estimativa.
O
memory_limitdo php.ini é o teto de um único script, não o consumo típico. Dividir a memória por ele dá o pior caso, não a média.
A conta de quantos processos PHP-FPM cabem na memória da VPS
(memória total − sistema operacional − banco de dados − cache − margem de segurança) ÷ memória média por processo = pm.max_children
O free -m mostra o total. Para MySQL, Redis ou Memcached, use ps ou smem filtrando pelo nome. O buffer do InnoDB (innodb_buffer_pool_size) tende a ser ocupado por inteiro: conte o valor configurado, não o consumo atual.
Exemplo de cálculo (ilustração)
Números inventados para mostrar a mecânica, não medida de nenhuma loja.
- VPS hipotética com 8.000 MB.
- Menos 1.000 MB do sistema: sobram 7.000 MB.
- Menos 2.000 MB do buffer do MySQL e 500 MB do Redis: sobram 4.500 MB.
- Menos 1.000 MB de margem: sobram 3.500 MB.
- Dividindo por 80 MB de média por processo, dá 43,75. Arredonde para baixo: o limite fica em 43.
O arquivo do pool costuma ser /etc/php/8.2/fpm/pool.d/www.conf no Debian e no Ubuntu, e /etc/php-fpm.d/www.conf na família Red Hat. Depois de alterar, recarregue com systemctl reload php8.2-fpm (ou php-fpm na Red Hat). Com pm = dynamic, mantenha start, min e max spare servers dentro do novo teto.
Os dois erros opostos: limite baixo trava a loja ociosa, limite alto leva ao swap e ao OOM killer
Limite baixo. O aviso aparece com a máquina folgada. É comum quando o www.conf padrão, que vem com pm.max_children = 5, nunca foi ajustado ao tamanho da VPS.
Limite alto. O PHP-FPM abre mais processos do que a memória comporta e o sistema passa a usar o swap, área do disco que faz papel de memória quando a RAM acaba. Como o disco é muito mais lento, a loja inteira responde devagar, inclusive o banco.
Quando a memória acaba de vez, o OOM killer (Out Of Memory killer) do Linux mata processos para liberá-la. Costuma escolher o maior, muitas vezes o MySQL, e aí aparece ‘Error establishing a database connection’.
Os sinais: swap em uso no free -m e ‘Out of memory’ ou ‘Killed process’ em dmesg -T ou journalctl -k. Regra prática: fila com memória sobrando pede mais processos; memória no teto pede menos. Para acompanhar isso continuamente, veja monitoramento de VPS.
Quando aumentar pm.max_children não resolve: processo esperando terceiro ou banco
Subir o limite não basta em dois casos:
- Processo esperando terceiro. Com API de frete, gateway ou antifraude lentos, o processo fica parado segurando memória. Mais processos só engrossam a fila no mesmo serviço, como mostra o artigo sobre checkout lento no pico.
- Banco no teto. Mais processos PHP mandam mais consultas para um recurso único e pioram o gargalo. Veja gargalo de banco MySQL na VPS.
Para saber qual é o seu caso, ligue o slow log no arquivo do pool: request_slowlog_timeout = 5s e slowlog apontando para um arquivo. Cada requisição mais lenta que isso grava o rastro do código, mostrando onde travou. Se ele aponta para chamada HTTP externa ou consulta ao banco, o problema não é o número de processos.
Outro sinal: depois de aumentar o limite, o tempo de resposta sobe junto com a fila. Antes de dimensionar, confira se a fila é de cliente ou de robô com a análise de logs do servidor.
Limite calculado, memória no fim e pico maior que a VPS: onde o burst entra
Limite calculado pela memória, sem swap, requisições rápidas, banco com folga, e mesmo assim o aviso aparece no pico: aí a máquina acabou de verdade.
Restam duas saídas: um plano maior de VPS, pago o mês inteiro, ou capacidade extra só nas horas de pico. A comparação está em servidor maior ou reforço só no pico.
No burst, servidores extras sobem na nuvem pública durante o pico e são removidos quando a demanda cai. Cada um traz memória e cota de processos PHP-FPM próprias, então a capacidade se soma em vez de todos disputarem a mesma RAM.
Para isso, a aplicação precisa rodar em contêiner, e sessão e upload precisam sair do disco local (veja estado local em múltiplos servidores). Se o slow log apontou terceiro ou banco, o burst não ajuda: só multiplica as requisições presas.
Falta servidor ou falta a conta dos processos?
Com ‘server reached pm.max_children’ e CPU tranquila, a primeira suspeita é a conta, não a máquina. Meça a memória por processo, desconte sistema, banco, cache e margem, e ajuste o limite. Se o aviso persiste com a memória no fim e as requisições rápidas, aí sim falta servidor.
Conversar no WhatsApp para avaliar se o seu caso é de conta de processos ou de falta de máquina
Perguntas frequentes
O que significa ‘server reached pm.max_children’ no log do PHP-FPM?
Significa que todos os processos PHP-FPM que atendem cliente estão ocupados e as próximas requisições esperam na fila. Se a espera fica longa, o visitante recebe 502 ou 504.
Qual é a diferença entre pm = static, dynamic e ondemand?
Static mantém sempre o número máximo de processos abertos, ideal para VPS dedicada à loja. Dynamic mantém uma faixa entre mínimo e máximo, ajustada por configurações. Ondemand abre processo quando chega requisição e o fecha depois de um tempo parado. Os três modos respeitam o mesmo teto, pm.max_children.
Como calcular o pm.max_children certo para a minha VPS?
Meça a memória real de cada processo PHP-FPM com ps ou smem durante o pico. Depois faça a conta: (memória total − sistema operacional − banco de dados − cache − margem de segurança) ÷ memória média por processo. Arredonde sempre para baixo e mantenha margem de segurança para os processos mais pesados.
Por que a loja fica lenta ou dá 502 se a CPU está ociosa?
Porque faltou atendente (processo PHP-FPM livre), não processador. Quando todos os processos estão ocupados, a requisição espera na fila. Se a fila transborda, recebe 502; se a espera passa do tempo limite do nginx, recebe 504.
Aumentar pm.max_children pode derrubar o servidor?
Sim, se o limite ficar acima do que a memória comporta. O sistema passará a usar swap, que é muito mais lento, e o OOM killer pode matar processos importantes como o MySQL. A regra prática: fila com memória sobrando pede mais processos, e memória no teto pede menos.