PHP FPM (FastCGI Process Manager) is a popular technology for processing php directives, particularly when used in conjunction with NGINX although it can be used with Apache.
In a common deployment scenario, the webserver is configured as a reverse-proxy with fpm providing the heavy lifting by processing the php code. Some of the most significant benefits of this approach are the ability to scale both up and out as your site or application grows.
Although every Linux distribution will work ‘out of the box’, there are a number of parameters which can be tuned to enhance performance.
We will explore the concept of pools in another post, but the Debian default pool configuration file is found at /etc/php/7.3/fpm/pool.d/www.conf
Other distributions will have a similarly located file.
The Parameters
ondemand | static | dymanic | ||
pm | Which process-manager to use. The default is dynamic. | * | * | * |
pm.max_children | The maximum number of child processes fpm will create (either as required, or at startup depending upon the pm parameter) | * | * | * |
pm.start_servers | How many child processes to create when fpm starts. | * | ||
pm.min_spare_servers | The minimum number of child processes fpm has idle in reserve, assuming pm.max_children has not been reached. | * | ||
pm.max_spare_servers | The maximum number of child processes fpm has idle in reserve | * | ||
pm.process_idle_timeout | Number of seconds the child process must be idle before it is killed. | * | ||
pm.max_requests | The maximum number of requests the child process will serve before being respawned. This will stop any memory leaks persisting for too long. | * | * | * |
Choosing a Process Manager
Each fpm child process can only fulfil one client request at a time, therefore it stands to reason that you need multiple processes to serve concurrent visitors. As you can see above, there are three different methods that fpm uses to choose how many child processes to create.
Static: Upon start up, fpm will create the number of child processes configured in pm.max_children
. No more, no less, and it will only ever have that many processes.
Dynamic: Upon start up, fpm will create the number of child processes configured in pm.start_servers
. As all these child processes become busy, fpm will create spares in accordance with pm.min_spare_servers
up to pm.max_children
. As child processes become idle again, the manager will kill them if more than pm.max_spare_servers
are running.
Ondemand: No child processes are created upon startup, but are created as required up to pm.max_children
, and killed again once they have been idle for pm.process_idle_timeout
seconds.
Which to use?
The very short answer is dynamic. It is the default configuration and ‘just works’ if your server is not overly stressed. It is the easiest to administer but as a consequence that which requires the most processes manger cycles to work out when to create and kill processes.
If your server is running at max capacity, then ondemand may well be a strong option. You will always only have the maximum number of processes needed to serve the current visitor numbers.