If you run a PHP-based site — WordPress, Laravel or a custom application — in production, much of the performance depends on the PHP-FPM configuration. PHP-FPM is the process manager that handles PHP requests, and when not tuned correctly it either wastes resources or slows your site down under load. This guide covers PHP-FPM configuration.
Related reading: Virtual host configuration · systemd service management
What Is PHP-FPM?
PHP-FPM (FastCGI Process Manager) is a service that runs PHP code and manages incoming requests through a process pool. When the web server (Nginx or Apache) receives a PHP request, it forwards it to PHP-FPM; a worker process in the PHP-FPM pool handles the request and returns the result.
This architecture separates the web server from PHP. So the web server responds quickly to static files while PHP work runs in a separate, scalable pool.
Process Manager (pm) Modes
The pm directive determines how the PHP-FPM pool behaves. There are three modes:
| Mode | Behavior | Suitable Scenario |
|---|---|---|
static | A fixed number of workers always open | High and stable traffic |
dynamic | Worker count varies with load | The default for most sites |
ondemand | Workers open only when a request arrives | Low traffic, many sites |
How to Calculate pm.max_children
The most critical setting is pm.max_children — it determines how many PHP requests can be processed at once. If this value is too low, requests queue and the site slows down; if too high, memory runs out.
The practical calculation is this: divide the memory you can allocate to PHP by the average memory usage of a single PHP worker. For example, if you allocated 2 GB to PHP and each worker uses about 64 MB on average, max_children should be roughly 30. You can measure a single worker's real memory usage with ps or monitoring tools.
Connecting PHP-FPM to Nginx
Nginx forwards PHP requests to PHP-FPM over a socket. A typical location block looks like this:
location ~ \.php$ {
include fastcgi_params;
fastcgi_pass unix:/run/php/php8.3-fpm.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}
unix:/run/php/...) is slightly faster than TCP on the same server. If the web server and PHP-FPM are on separate machines, TCP (127.0.0.1:9000) is used.Common PHP-FPM Errors
- 502 Bad Gateway: PHP-FPM is not running or the socket path is wrong. Check with
systemctl status php8.3-fpm. - 504 Gateway Timeout: The PHP script takes too long; check
max_execution_timeand Nginx'sfastcgi_read_timeout. - Requests waiting in queue:
max_childrenis insufficient — increase it if memory allows. - Memory running out:
max_childrenis too high; lower it or add RAM.
Frequently Asked Questions
Which pm mode should I choose?
For most sites dynamic is a balanced choice. If your traffic is high and stable, static gives more predictable performance. If there are many low-traffic sites on one server, ondemand conserves memory.
I changed a PHP-FPM setting, how do I apply it?
After a configuration change, run sudo systemctl reload php8.3-fpm. reload applies the settings without interrupting current requests.
Should I also enable OPcache?
Yes. OPcache keeps compiled PHP code in memory, avoiding recompilation on every request and noticeably improving PHP performance — it should definitely be on in production.
Go live on infrastructure where PHP-FPM and OPcache are optimized from the start with KEYDAL hosting solutions. Explore KEYDAL hosting