If your Nginx server is returning 502 Bad Gateway errors, or your site slows to a crawl under traffic, PHP-FPM configuration is almost always the culprit. Understanding how PHP-FPM works — and how to tune it — is one of the most valuable server management skills you can have.
What Is PHP-FPM?
PHP-FPM (FastCGI Process Manager) is the component that actually executes your PHP code. When a visitor requests a PHP page, Nginx passes that request to PHP-FPM, which runs the code and returns HTML back to Nginx to serve to the visitor.
PHP-FPM manages a pool of worker processes — pre-forked PHP processes waiting to handle requests. The number of workers available determines how many simultaneous PHP requests your server can process. If all workers are busy when a new request arrives, it queues. If the queue fills, visitors get 502 errors.
Key PHP-FPM Configuration Parameters
The PHP-FPM pool config lives at: /etc/php/8.x/fpm/pool.d/www.conf (Ubuntu) or in aaPanel at /www/server/php/81/etc/php-fpm.conf
| Parameter | What It Controls | Default | Recommended Starting Point |
|---|---|---|---|
| pm | Process management mode | dynamic | dynamic (for most sites) |
| pm.max_children | Maximum simultaneous PHP processes | 5 | (RAM in MB ÷ 40) — see below |
| pm.start_servers | Processes started on boot | 2 | pm.max_children ÷ 4 |
| pm.min_spare_servers | Minimum idle processes | 1 | pm.max_children ÷ 4 |
| pm.max_spare_servers | Maximum idle processes | 3 | pm.max_children ÷ 2 |
| pm.max_requests | Requests before worker restart | 0 (unlimited) | 500 (prevents memory leaks) |
| request_terminate_timeout | Max time for a single request | 0 | 60s |
Calculating pm.max_children
The most important value. Setting it too low causes 502 errors. Setting it too high causes OOM (out of memory) kills that crash everything.
Formula: (Available RAM in MB) ÷ (Average PHP process size in MB) = max_children
Check your average PHP process size:
ps --no-headers -o rss,cmd -C php-fpm8.1 | awk "{ sum+=\$1 } END { printf \"Avg: %dMB\", sum/NR/1024 }"
Example: 2GB VPS with 1.5GB available for PHP, average process size 45MB → max_children = 33
Process Management Modes
- dynamic — starts a minimum number of workers and spawns more as needed up to max_children. Best for most sites.
- static — always keeps max_children processes running. Uses more RAM but handles traffic spikes better. Best for high-traffic sites.
- ondemand — spawns workers only when needed, kills them when idle. Best for low-traffic or development servers with many pools.
Multiple Pools — One Per Site
On a server with multiple websites, each site should have its own PHP-FPM pool. This improves security (each site runs under its own user) and performance (a misbehaving site cannot exhaust workers for other sites).
In aaPanel, each site automatically gets its own pool. Check them at /www/server/php/81/etc/php-fpm.conf.d/
After Changing Configuration
# Test config for errors first
php-fpm8.1 -t
# Reload gracefully (no downtime)
systemctl reload php8.1-fpm
Related Reading
- 5 Signs Your Server Needs Immediate Attention — 502 errors are sign #5
- How to Set Up aaPanel on a VPS — PHP-FPM is configured during aaPanel setup
Is PHP-FPM Causing Your 502 Errors?
NextCode Solutions diagnoses and tunes PHP-FPM configurations for WordPress and PHP sites on Nginx VPS servers. Usually resolved same day.
Get Server Help