Nginx+PHP-FPM快速耗尽max_children问题排查求助
Alright, let's dig into why your 4vCPU/8GB server is burning through PHP-FPM max_children so fast (even just 2-5 minutes after restarting), and walk through fixes step by step.
核心问题:大量超时请求耗尽进程
First off, your PHP-FPM logs tell the whole story: every warning is about /index.php execution timing out (60-78 seconds). When a PHP-FPM child process hits an execution timeout, it gets terminated immediately. But if your server is flooded with these slow requests, PHP-FPM will keep spinning up new child processes to handle incoming traffic—until it hits pm.max_children=120 and can't create any more.
On top of that, your current PHP-FPM pm settings are way too aggressive for a 4vCPU/8GB server, which makes the problem worse.
Step 1: Fix the root cause—slow scripts
This is the most critical part. If your /index.php is taking 60+ seconds to run, you need to find out why. Here's how:
- Enable PHP-FPM slow logs: Add these lines to your PHP-FPM pool config (e.g.,
www.conf):
Any script taking over 10 seconds will log its execution trace here—this will show you exactly which functions/queries are dragging things down.slowlog = /var/log/php-fpm/www-slow.log request_slowlog_timeout = 10s - Check for common bottlenecks:
- Database queries: Are you missing indexes? Run
EXPLAINon slow queries to spot full table scans. - External API calls: If your app calls third-party services, make sure you've set reasonable timeouts (e.g., 5-10 seconds instead of waiting indefinitely).
- Resource leaks/loops: Look for infinite loops, unclosed database connections, or heavy file operations that block execution.
- Database queries: Are you missing indexes? Run
Step 2: Optimize PHP-FPM pm settings
Your current dynamic pm parameters are way too high for your server resources. Let's adjust them:
- Calculate reasonable
pm.max_children:
First, find out how much memory each PHP-FPM child uses with this command:
For an 8GB server, subtract ~1-2GB for the OS/Nginx/database, then divide by the average process size. For example, if each process uses 80MB:ps aux | grep php-fpm | awk '{sum+=$6} END {print "Avg PHP-FPM memory per process: " sum/NR/1024 " MB"}'(8192 - 1536) / 80 = 83→ setpm.max_children=80(round down for safety). - Adjust spare server counts:
These control how many idle child processes PHP-FPM keeps around. For 4vCPU:
Too many spare processes waste memory, which makes your server slower and more prone to timeouts.pm.min_spare_servers = 8 # 2x CPU cores pm.max_spare_servers = 16 # 2x min_spare - Keep
pm.max_requests=500:
This is good—it restarts child processes after 500 requests to prevent memory leaks, so no need to change this. - Set a reasonable timeout:
Addrequest_terminate_timeout = 60sto your pool config. This ensures PHP-FPM kills stuck processes after 60 seconds (matches the timeout in your logs), instead of letting them hang longer.
Step 3: Tweak Nginx fastcgi settings
Your current buffer settings are too small for most PHP apps, which can cause unnecessary delays:
location ~ \.php$ { fastcgi_split_path_info ^(.+\.php)(/.+)$; fastcgi_pass unix:/run/php/php7.4-fpm.sock; fastcgi_index index.php; include fastcgi_params; fastcgi_read_timeout 300; fastcgi_buffer_size 64k; # Increased from 4k fastcgi_buffers 4 64k; # Increased from 32x4k fastcgi_busy_buffers_size 128k; # Add this to handle peak traffic }
Also, make sure your Nginx worker_processes is set to auto (or 4, matching your CPU cores) to maximize request handling capacity.
Quick Summary
- Fix slow scripts first—this is the root cause of process exhaustion.
- Tune PHP-FPM pm parameters to match your server's memory/CPU, not just set arbitrary high values.
- Optimize Nginx buffers to avoid unnecessary request delays.
内容的提问来源于stack exchange,提问作者Tuan Chu

