O PHP-FPM tuning é uma das etapas mais importantes para melhorar o desempenho de servidores Linux que executam WordPress, WooCommerce, aplicações PHP, Laravel, Magento, Drupal e outros sistemas baseados em PHP.
Um servidor pode possuir vários núcleos de CPU e muita memória RAM e, mesmo assim, apresentar lentidão, erros 502, filas de requisições e consumo excessivo de recursos quando o PHP-FPM está configurado de maneira inadequada.
O problema geralmente não está simplesmente na versão do PHP. Em muitos ambientes, o gargalo aparece na forma como os processos PHP são criados, mantidos, reutilizados e limitados.
Neste guia, vamos analisar como realizar PHP-FPM tuning em VPS e servidores dedicados, incluindo:
pmpm.max_childrenpm.start_serverspm.min_spare_serverspm.max_spare_serverspm.max_requestsrequest_terminate_timeout- consumo de memória
- CPU
- PHP-FPM status
- slowlog
- OPcache
- Nginx
- Apache
- 502 Bad Gateway
- dimensionamento de workers
- monitoramento
- ajustes para WordPress
- diferenças entre VPS e servidor dedicado
A ideia não é simplesmente copiar uma configuração pronta, mas entender como dimensionar o PHP-FPM de acordo com os recursos reais do servidor e o comportamento da aplicação.
O que é PHP-FPM?
PHP-FPM significa PHP FastCGI Process Manager.
Ele é responsável por executar processos PHP e disponibilizá-los para servidores web como Nginx ou Apache.
Em uma arquitetura típica, temos:
Cliente
↓
Nginx / Apache
↓
PHP-FPM
↓
PHP
↓
WordPress / Laravel / Aplicação
↓
MariaDB / MySQL / Redis
Quando um usuário acessa uma página dinâmica, o servidor web encaminha a requisição para o PHP-FPM.
O PHP-FPM utiliza processos ou workers para executar o código PHP.
Se existem poucos workers disponíveis, requisições ficam esperando.
Se existem workers demais, o servidor pode começar a consumir memória excessivamente e entrar em pressão de RAM ou swap.
É exatamente nesse ponto que o PHP-FPM tuning se torna importante.
Por que o PHP-FPM precisa ser ajustado?
A configuração padrão do PHP-FPM não necessariamente corresponde ao ambiente onde o servidor será utilizado.
Um VPS com:
- 2 vCPUs
- 4 GB RAM
- 3 sites WordPress
possui necessidades completamente diferentes de um servidor dedicado com:
- 16 cores
- 64 GB RAM
- 100 sites
- WooCommerce
- aplicações PHP
- banco de dados local
Um valor de pm.max_children adequado para um servidor pode ser completamente inadequado para outro.
Por isso, o princípio mais importante é:
Não dimensione PHP-FPM apenas pela quantidade de RAM disponível. Analise memória, CPU, carga, tempo de execução das requisições e comportamento da aplicação.
Onde fica a configuração do PHP-FPM?
A localização depende da distribuição Linux e da versão do PHP.
Em sistemas baseados em Debian ou Ubuntu, exemplos comuns incluem:
/etc/php/8.2/fpm/
ou:
/etc/php/8.3/fpm/
Em distribuições baseadas em RHEL, AlmaLinux, Rocky Linux ou CentOS, podem existir caminhos como:
/etc/php-fpm.conf
e:
/etc/php-fpm.d/
Para descobrir o arquivo carregado pelo PHP-FPM:
php-fpm8.3 -i | grep "Loaded Configuration"
Dependendo da distribuição, o binário pode ser:
php-fpm
ou:
php-fpm8.2
Também é possível verificar o serviço:
systemctl status php8.3-fpm
ou:
systemctl status php-fpm
Entendendo o parâmetro pm
O parâmetro mais importante para começar o PHP-FPM tuning é:
pm =
Ele define como os processos PHP serão gerenciados.
Os modos principais são:
pm = static
pm = dynamic
e:
pm = ondemand
Cada um possui características diferentes.
PHP-FPM com pm = dynamic
O modo dynamic mantém uma quantidade variável de processos PHP.
Exemplo:
pm = dynamic
pm.max_children = 30
pm.start_servers = 5
pm.min_spare_servers = 5
pm.max_spare_servers = 15
Nesse modelo, o PHP-FPM cria processos conforme a necessidade, mantendo processos disponíveis para atender novas requisições.
É uma opção bastante utilizada em servidores web.
Pode funcionar muito bem em:
- WordPress
- WooCommerce
- sites corporativos
- APIs
- aplicações PHP
- servidores com tráfego variável
PHP-FPM com pm = ondemand
No modo ondemand, os processos são criados somente quando existe demanda.
Exemplo:
pm = ondemand
pm.max_children = 30
pm.process_idle_timeout = 10s
pm.max_requests = 500
Isso pode ser interessante para servidores com muitos sites e tráfego irregular.
Por exemplo, imagine um servidor com dezenas de pequenos sites:
Site A → pouco tráfego
Site B → pouco tráfego
Site C → pouco tráfego
...
Site Z → picos ocasionais
Manter workers permanentemente ativos para todos os pools pode desperdiçar memória.
Nesse cenário, ondemand pode ser útil.
PHP-FPM com pm = static
No modo static, o número de processos é definido diretamente por:
pm.max_children
Exemplo:
pm = static
pm.max_children = 40
Nesse modelo, o PHP-FPM mantém a quantidade configurada de workers.
Pode ser interessante em ambientes previsíveis e com bastante memória disponível.
Porém, utilizar valores muito altos sem dimensionamento pode causar problemas graves.
O parâmetro mais importante: pm.max_children
O:
pm.max_children
define o número máximo de processos PHP-FPM que podem existir simultaneamente.
Por exemplo:
pm.max_children = 20
significa que até 20 workers poderão executar requisições simultaneamente.
Isso não significa que você deve simplesmente definir:
pm.max_children = 1000
em um servidor poderoso.
Cada processo PHP pode consumir memória significativa.
Se cada worker consumir aproximadamente 150 MB, 100 workers poderiam representar:
150 MB × 100
=
15 GB
E isso é apenas uma aproximação do PHP-FPM.
Ainda precisamos considerar:
- sistema operacional
- Nginx
- Apache
- MariaDB
- Redis
- OPcache
- serviços de monitoramento
- aplicações auxiliares
- cache
- buffers
- kernel
- outros processos
Portanto, o dimensionamento precisa considerar o consumo real.
Como calcular pm.max_children
Uma abordagem prática é medir o consumo médio de memória dos processos PHP-FPM.
Primeiro:
ps --no-headers -o rss,cmd -C php-fpm
Em sistemas com PHP-FPM versionado:
ps --no-headers -o rss,cmd -C php-fpm8.3
Também podemos utilizar:
ps aux | grep php-fpm
Para analisar a memória:
ps -ylC php-fpm --sort:rss
O RSS normalmente é apresentado em KB.
Por exemplo, suponha que os workers estejam consumindo aproximadamente:
120 MB
130 MB
125 MB
140 MB
135 MB
Podemos utilizar uma média aproximada de:
130 MB por worker
Se reservamos 4 GB para PHP-FPM:
4096 MB / 130 MB
≈ 31 workers
Porém, não devemos consumir toda a memória disponível.
Se o servidor possui 8 GB RAM, talvez seja necessário reservar memória para:
- sistema
- MariaDB
- Nginx
- Redis
- cache
- filesystem
- outros serviços
Portanto, o valor final pode ser consideravelmente menor.
Exemplo para VPS com 4 GB RAM
Imagine:
RAM: 4 GB
CPU: 2 vCPU
Nginx
PHP-FPM
MariaDB
WordPress
Redis
Uma configuração inicial poderia ser:
pm = dynamic
pm.max_children = 12
pm.start_servers = 3
pm.min_spare_servers = 2
pm.max_spare_servers = 5
pm.max_requests = 500
Isso não significa que esses valores sejam universais.
Depois da aplicação da configuração, devemos observar:
free -h
top
htop
e:
vmstat 1
Se houver muita memória disponível e fila de requisições, podemos aumentar gradualmente.
Exemplo para VPS com 8 GB RAM
Considere:
8 GB RAM
4 vCPU
Nginx
PHP-FPM
MariaDB
WordPress
Redis
Uma configuração inicial possível:
pm = dynamic
pm.max_children = 20
pm.start_servers = 4
pm.min_spare_servers = 4
pm.max_spare_servers = 8
pm.max_requests = 500
Depois é necessário medir.
Se os workers estiverem consumindo muita RAM:
free -h
Se houver swap crescente:
swapon --show
e:
vmstat 1
podem ajudar a identificar pressão de memória.
Exemplo para servidor dedicado
Considere agora:
64 GB RAM
16 cores
Nginx
PHP-FPM
MariaDB
Redis
WordPress/WooCommerce
É possível trabalhar com valores muito maiores, mas isso não significa que devemos simplesmente configurar centenas de workers.
Um ponto inicial poderia ser:
pm = dynamic
pm.max_children = 80
pm.start_servers = 10
pm.min_spare_servers = 10
pm.max_spare_servers = 30
pm.max_requests = 1000
Depois devemos avaliar:
- RAM disponível
- CPU
- tempo médio de execução
- número de requisições
- fila do PHP-FPM
- banco de dados
- cache
- I/O
pm.max_requests
Outro parâmetro importante é:
pm.max_requests
Ele define quantas requisições um processo poderá atender antes de ser encerrado e criado novamente.
Exemplo:
pm.max_requests = 500
Isso pode ser útil quando uma aplicação ou extensão apresenta crescimento gradual de memória.
Por exemplo:
Worker inicia → 100 MB
Após centenas de requisições → 140 MB
Após milhares → 200 MB
Recriar periodicamente o processo pode ajudar a controlar esse crescimento.
Valores comuns podem variar bastante:
pm.max_requests = 300
pm.max_requests = 500
pm.max_requests = 1000
Não existe um valor universal.
request_terminate_timeout
Aplicações PHP podem apresentar requisições extremamente demoradas.
Por exemplo:
PHP inicia
↓
consulta banco
↓
API externa demora
↓
plugin executa operação pesada
↓
requisição fica presa
Podemos configurar:
request_terminate_timeout = 120s
Assim, uma requisição que ultrapassar o limite poderá ser encerrada.
Em aplicações específicas, pode ser necessário utilizar valores maiores.
Por isso, não devemos colocar um timeout muito agressivo sem compreender o comportamento da aplicação.
PHP-FPM e CPU
Um erro comum é dimensionar PHP-FPM exclusivamente com base na RAM.
CPU também é extremamente importante.
Imagine:
4 cores
100 workers PHP
Isso não significa que 100 requisições serão processadas simultaneamente de forma eficiente.
Se todas exigirem muito processamento:
100 processos
↓
4 cores
↓
competição por CPU
↓
load average elevado
↓
latência
Mais workers podem aumentar a concorrência, mas também podem aumentar a disputa por recursos.
Por isso, mais workers não significa automaticamente mais performance.
Como verificar o Load Average
Utilize:
uptime
ou:
cat /proc/loadavg
Também:
top
Em um servidor com 4 CPUs, um load de 2 pode representar uma situação muito diferente de um load de 20.
O load average precisa ser interpretado junto com:
- número de CPUs
%CPU%iowait- processos bloqueados
- latência de disco
Use vmstat durante o tuning
O comando:
vmstat 1
é extremamente útil.
Observe principalmente:
r
si
so
wa
Onde:
rrepresenta processos aguardando CPUsiindica swap insoindica swap outwaindica espera por I/O
Se o servidor estiver constantemente com wa elevado, o problema pode estar relacionado a armazenamento.
Se si e so estiverem ativos continuamente, pode existir pressão de memória.
PHP-FPM e OPcache
O OPcache é praticamente obrigatório em ambientes PHP modernos de produção.
Ele mantém bytecode PHP compilado em memória, reduzindo a necessidade de recompilar scripts a cada requisição.
Exemplo:
opcache.enable=1
opcache.memory_consumption=256
opcache.interned_strings_buffer=32
opcache.max_accelerated_files=30000
opcache.validate_timestamps=1
opcache.revalidate_freq=2
Os valores dependem da aplicação.
Em servidores WordPress com muitos plugins e temas, pode ser necessário aumentar:
opcache.max_accelerated_files
O tamanho do OPcache também precisa ser compatível com a memória disponível.
PHP-FPM com Nginx
Uma arquitetura muito comum é:
Internet
↓
Nginx
↓
PHP-FPM
↓
WordPress
Um exemplo de configuração do Nginx:
location ~ \.php$ {
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_pass unix:/run/php/php8.3-fpm.sock;
}
O socket pode variar conforme a distribuição.
Verifique:
ls -lah /run/php/
PHP-FPM com Apache
O PHP-FPM também pode ser utilizado com Apache.
Uma arquitetura possível:
Internet
↓
Apache
↓
PHP-FPM
↓
PHP
Nesse cenário, é importante evitar configurações concorrentes desnecessárias.
Por exemplo, executar PHP através de múltiplos mecanismos simultaneamente pode complicar o dimensionamento.
Como identificar saturação do PHP-FPM
Um dos sinais mais importantes é o aparecimento de:
502 Bad Gateway
Especialmente quando o Nginx está funcionando, mas o PHP-FPM não consegue responder adequadamente.
Verifique:
systemctl status php8.3-fpm
Depois:
journalctl -u php8.3-fpm --since "1 hour ago"
Também procure mensagens relacionadas a:
server reached pm.max_children
Essa mensagem é especialmente importante.
Quando aparece:
WARNING: [pool www] server reached pm.max_children setting
significa que o pool atingiu o limite configurado.
Isso pode indicar que:
- existem requisições demais;
- os workers estão demorando muito;
- o
pm.max_childrenestá baixo; - a aplicação está lenta;
- o banco de dados está lento;
- existe algum processo PHP travando.
Não significa automaticamente que devemos aumentar o limite.
Antes de aumentar pm.max_children
Imagine:
pm.max_children = 20
e o log mostra:
server reached pm.max_children
A reação mais comum é:
pm.max_children = 50
Porém, primeiro precisamos descobrir por que os 20 workers estão ocupados.
Se cada requisição demora 10 segundos porque o MariaDB está lento, aumentar para 50 pode simplesmente criar:
50 PHP
↓
50 consultas ao banco
↓
MariaDB sobrecarregado
↓
mais latência
↓
mais PHP esperando
O problema pode ficar pior.
Ative o slowlog
O PHP-FPM possui mecanismos para identificar requisições lentas.
Exemplo:
request_slowlog_timeout = 5s
slowlog = /var/log/php-fpm/www-slow.log
Assim, requisições que ultrapassarem o limite podem gerar informações úteis.
Depois:
tail -f /var/log/php-fpm/www-slow.log
O caminho pode variar conforme a distribuição.
Essa informação pode revelar:
- plugin lento
- script PHP pesado
- consulta problemática
- API externa
- operação de arquivo
- código bloqueado
Status do PHP-FPM
Também é possível habilitar o status do PHP-FPM.
Exemplo:
pm.status_path = /fpm-status
Depois podemos obter informações sobre o pool.
Entre os dados úteis estão:
- active processes
- idle processes
- total processes
- max active processes
- max children reached
- requests
Essas métricas ajudam muito no dimensionamento.
Em produção, o endpoint deve ser protegido para não ficar publicamente acessível.
PHP-FPM e WordPress
WordPress é um caso particularmente interessante.
Um único acesso pode envolver:
- WordPress core
- tema
- plugins
- banco de dados
- Redis
- APIs externas
- filesystem
- WooCommerce
Por isso, uma requisição PHP pode ser extremamente rápida ou bastante pesada.
Uma instalação simples pode consumir poucos recursos.
Uma instalação WooCommerce com muitos plugins pode consumir muito mais.
Redis pode reduzir pressão sobre PHP
O Redis pode ajudar a reduzir consultas repetitivas ao banco através de object cache.
Arquitetura:
Usuário
↓
Nginx
↓
PHP-FPM
↓
Redis
↓
MariaDB
O objetivo não é substituir o banco de dados, mas reduzir operações repetitivas.
Isso pode diminuir o tempo de execução de determinadas requisições PHP.
Não confunda PHP-FPM com cache de página
O PHP-FPM executa PHP.
Page cache evita que determinadas requisições precisem chegar ao PHP.
Por exemplo:
Usuário
↓
Nginx
↓
Cache
↓
HTML
Se uma página puder ser servida diretamente pelo cache, o PHP-FPM nem precisa processá-la.
Isso é extremamente importante para WordPress de alto tráfego.
Configuração exemplo para VPS
Para um VPS com aproximadamente:
4 vCPU
8 GB RAM
Nginx
PHP 8.3
MariaDB
WordPress
Redis
uma configuração inicial poderia ser:
[www]
user = www-data
group = www-data
listen = /run/php/php8.3-fpm.sock
pm = dynamic
pm.max_children = 20
pm.start_servers = 4
pm.min_spare_servers = 4
pm.max_spare_servers = 8
pm.max_requests = 500
request_terminate_timeout = 120s
request_slowlog_timeout = 5s
slowlog = /var/log/php-fpm/www-slow.log
Depois do ajuste:
systemctl restart php8.3-fpm
E acompanhe:
systemctl status php8.3-fpm
Configuração exemplo para servidor dedicado
Considere:
16 cores
64 GB RAM
Nginx
PHP-FPM
MariaDB
Redis
WordPress/WooCommerce
Um ponto inicial poderia ser:
pm = dynamic
pm.max_children = 80
pm.start_servers = 10
pm.min_spare_servers = 10
pm.max_spare_servers = 30
pm.max_requests = 1000
request_terminate_timeout = 120s
request_slowlog_timeout = 5s
Novamente, esses valores devem ser validados através de métricas.
Como fazer tuning de forma segura
Uma metodologia melhor é:
1. Medir
Colete:
free -h
uptime
vmstat 1
top
iostat -xz 1
e dados do PHP-FPM.
2. Alterar pouco
Evite mudar dez parâmetros simultaneamente.
Por exemplo:
pm.max_children = 20
para:
pm.max_children = 25
3. Observar
Monitore durante períodos de tráfego real.
4. Comparar
Observe:
- latência
- erros 502
- CPU
- RAM
- swap
- load
- requisições
- tempo de resposta
5. Repetir
Faça novos ajustes somente depois de entender os resultados.
PHP-FPM tuning para VPS com pouca memória
Em VPS pequenos, o maior risco geralmente é criar workers demais.
Imagine:
2 GB RAM
e:
pm.max_children = 50
Se cada processo utilizar 100 MB:
50 × 100 MB
=
5 GB
O resultado pode ser:
RAM insuficiente
↓
swap
↓
latência
↓
OOM Killer
↓
processos encerrados
Nesse ambiente, é melhor limitar a concorrência e otimizar a aplicação.
PHP-FPM tuning para servidor dedicado
Em servidores dedicados, existe maior capacidade para trabalhar com mais concorrência.
Porém, isso não elimina a necessidade de dimensionamento.
Se o servidor possui:
32 cores
128 GB RAM
não significa que:
pm.max_children = 500
será automaticamente melhor.
É necessário observar o consumo médio de cada processo e a capacidade dos demais componentes.
O impacto do banco de dados
Muitos problemas atribuídos ao PHP-FPM são causados pelo banco.
Exemplo:
PHP-FPM
↓
MariaDB
↓
consulta demora 8 segundos
↓
worker fica ocupado
Se temos:
30 workers
e cada um permanece ocupado esperando o banco, podemos atingir:
pm.max_children
rapidamente.
Por isso, antes de aumentar PHP-FPM, investigue:
mysqladmin processlist
e ferramentas de análise do MariaDB.
PHP-FPM e I/O
Outra possibilidade é armazenamento lento.
Uma requisição pode estar esperando:
- leitura de arquivo
- escrita de sessão
- logs
- banco de dados
- filesystem
- armazenamento remoto
Nesse caso, aumentar workers pode aumentar a quantidade de operações simultâneas de I/O.
Analise:
iostat -xz 1
Observe especialmente:
await
util
%util
Em servidores com NVMe, a latência normalmente é muito menor do que em HDD, mas aplicações mal configuradas ainda podem gerar gargalos.
Como saber se o tuning funcionou?
Não use somente a sensação de velocidade.
Compare métricas.
Antes:
CPU: 80%
RAM: 90%
502: 50/h
PHP max children reached: frequente
Depois:
CPU: 65%
RAM: 75%
502: 2/h
PHP max children reached: ocasional
Isso fornece uma avaliação muito mais confiável.
Checklist de PHP-FPM tuning
Antes de considerar o ajuste concluído, verifique:
pmadequado ao ambientepm.max_childrendimensionadopm.start_serversconfiguradopm.min_spare_serversconfiguradopm.max_spare_serversconfiguradopm.max_requestsavaliado- timeout configurado
- slowlog habilitado quando necessário
- OPcache configurado
- CPU monitorada
- RAM monitorada
- swap monitorada
- I/O monitorado
- MariaDB analisado
- Nginx/Apache analisado
- erros 502 monitorados
- logs do PHP-FPM analisados
Conclusão
O PHP-FPM tuning deve ser tratado como um processo de dimensionamento e monitoramento, não como uma simples aplicação de valores encontrados na internet.
Os principais parâmetros, como:
pm.max_children
pm.start_servers
pm.min_spare_servers
pm.max_spare_servers
pm.max_requests
precisam ser ajustados considerando:
- quantidade de RAM;
- número de CPUs;
- consumo real dos workers;
- quantidade de sites;
- tráfego;
- complexidade das aplicações;
- banco de dados;
- cache;
- armazenamento;
- comportamento das requisições.
Em VPS pequenos, o cuidado principal é evitar excesso de workers e pressão de memória.
Em servidores dedicados, existe mais espaço para aumentar a concorrência, mas ainda é necessário observar CPU, banco de dados, I/O e tempo de execução.
O melhor resultado normalmente vem da combinação de PHP-FPM + OPcache + cache de aplicação + Redis quando apropriado + banco de dados otimizado + monitoramento contínuo.
Mais workers não significam necessariamente mais velocidade. O objetivo do tuning é encontrar o ponto em que o servidor consegue atender a demanda sem desperdiçar recursos ou criar novos gargalos.
FAQ — PHP-FPM Tuning
É o processo de ajustar os parâmetros do PHP-FPM para adequar a execução dos processos PHP aos recursos disponíveis no servidor e à demanda da aplicação.
O pm.max_children é um dos parâmetros mais importantes porque limita a quantidade de processos PHP-FPM simultâneos.
pm.max_children? Não existe um valor universal. O ideal é medir o consumo médio de memória dos workers e considerar a RAM reservada para o sistema, banco de dados e demais serviços.
pm.max_children deixa o servidor mais rápido? Não necessariamente. Se o gargalo estiver no banco de dados, CPU, disco ou aplicação PHP, aumentar o número de workers pode inclusive aumentar a pressão sobre esses recursos.
Depende do ambiente. dynamic mantém processos disponíveis e pode funcionar bem para tráfego contínuo. ondemand pode ser interessante quando existem muitos sites ou tráfego irregular.
Sim. Saturação, processos indisponíveis, problemas no socket, timeouts ou falhas do serviço PHP-FPM podem contribuir para erros 502.
server reached pm.max_children? Significa que o pool atingiu o número máximo de processos configurado em pm.max_children. É um sinal que deve ser investigado antes de simplesmente aumentar o limite.
pm.max_requests é importante? Sim. Ele pode ajudar a controlar processos que apresentam crescimento de memória ao longo do tempo, fazendo com que sejam recriados após atender determinado número de requisições.
Para ambientes PHP de produção, o OPcache normalmente é altamente recomendado porque reduz o trabalho necessário para compilar scripts PHP repetidamente.
Você pode utilizar logs, PHP-FPM status, slowlog, top, htop, vmstat, iostat, Zabbix, Prometheus e outras ferramentas de monitoramento.
Veja Também:
Como Otimizar VPS, Servidor Dedicado ou Cloud: Guia Completo
CPU 100%: Diferenças Entre VM e Bare Metal no Servidor
iowait Alto NVMe Cloud: Como Diagnosticar Gargalo de Disco
Load Average em Ambiente Virtualizado: Como Interpretar VPS e Cloud
Steal Time Alto na VPS: O Que É e Como Resolver o Gargalo
Como Medir Performance de Servidor Linux na Prática (Além da CPU)
VPS Lenta? Guia de Diagnóstico, Otimização e Escalonamento
