Apache travando? Ajusta memória e para de sofrer

Se o Apache congela, 99% das vezes é porque você deixou ele spawnar mais processo do que sua RAM aguenta. Simples assim.

1) Descubra quanto cada processo consome

Antes de sair chutando número:

ps aux | grep apache2

ou:

ps -ylC apache2 --sort:rss

Olha o RSS (memória). Exemplo realista:

60MB por processo

Guarda isso.


2) Calcule o limite REAL de processos

Regra prática (sem romantismo):

RAM disponível / memória por processo = MaxRequestWorkers

Exemplo:

  • 2GB RAM livre
  • 60MB por processo
2000 / 60 = ~33 processos

Configura no máximo ~30, não 150 igual tutorial lixo.


3) Ajustes no MPM (isso aqui é o core do problema)

Se usa prefork (com mod_php velho)

Arquivo:

/etc/apache2/mods-enabled/mpm_prefork.conf

Configuração decente:

<IfModule mpm_prefork_module>
    StartServers             5
    MinSpareServers          5
    MaxSpareServers          10
    MaxRequestWorkers        30
    MaxConnectionsPerChild   300
</IfModule>

Explicação rápida (sem aula):

  • MaxRequestWorkers → limite de processos (o mais importante)
  • MaxConnectionsPerChild → mata processo antes de vazar memória
  • Start/Spare → só controle de spawn, não é gargalo

4) Se ainda usa prefork… pare

Prefork + mod_php = consumo absurdo.

Vai pra:

  • mpm_event + PHP-FPM

Ativa:

a2dismod mpm_prefork
a2enmod mpm_event proxy_fcgi setenvif
a2enconf php8.2-fpm

5) Ajuste o PHP-FPM (onde a RAM morre de verdade)

Arquivo:

/etc/php/8.2/fpm/pool.d/www.conf

Parâmetros chave:

pm = dynamic
pm.max_children = 30
pm.start_servers = 5
pm.min_spare_servers = 5
pm.max_spare_servers = 10
pm.max_requests = 500

Mesma lógica:

pm.max_children = limite baseado na RAM

Se errar aqui, não importa o Apache — vai travar igual.


6) Timeout: corta requisição zumbi

Timeout 30

Evita request pendurado segurando worker.


7) KeepAlive (ajuste fino, mas ajuda)

KeepAlive On
MaxKeepAliveRequests 100
KeepAliveTimeout 2

Timeout alto = conexão segurando worker à toa.


8) Evite leak infinito

Apache:

MaxConnectionsPerChild 300

PHP-FPM:

pm.max_requests = 500

Isso força reciclagem → evita consumo crescente.


9) Swap NÃO é solução

Se entrou swap:

já perdeu performance

Swap é airbag, não motor.


10) Teste carga (não seja amador)

ab -n 1000 -c 50 http://localhost/

ou melhor:

wrk -t4 -c50 -d30s http://localhost/

Se travar aqui, ia travar em produção.


TL;DR (pra quem lê log, não tutorial)

  • Descobre consumo real por processo
  • Calcula limite baseado na RAM
  • Ajusta MaxRequestWorkers / pm.max_children
  • Mata processos periodicamente
  • Usa mpm_event + PHP-FPM
  • KeepAlive curto
  • Timeout baixo

Erro clássico (pra evitar vergonha)

  • Colocar MaxRequestWorkers 500 em VPS de 2GB
  • Usar prefork em 2026
  • Ignorar PHP-FPM
  • Achar que CPU é o problema (quase nunca é)
Rolar para cima