PHP-FPM Sizing

Sizing a PHP server is essential because it allows you to optimize internal resources and avoid potential system downtime. By default, PHP-FPM comes with a standard configuration that should be adjusted based on the server’s performance, the number of active processes, and the average consumption of a single process.

Each PHP worker handles one request at a time, and when all resources are occupied, new ones are placed in a queue. Once the resource limit is exceeded, Nginx may return various errors or, in the worst cases, the service might go down.

The first thing to evaluate is the PHP server parameters that control when and how many processes are created and maintained. At service startup, a fixed number of servers is initialized (defined within the parameter pm.start_servers). As processes become idle, they remain available, so it’s useful to configure how many idle servers (minimum and maximum) we want in our infrastructure. Having a minimum number of idle servers helps prevent delays in handling requests since they can be assigned immediately, while setting a maximum number of idle processes helps avoid memory waste.

To perform correct sizing, it is necessary to take your server’s hardware values as a reference.

A standard starting configuration is to use about 10–15% of servers as idle processes and 20–30% as maximum. With these values, we obtain an initial number of start_servers equal to 20% of the processes.

  pm = dynamic
  pm.start_servers = X
  pm.min_spare_servers = Y
  pm.max_spare_servers = X
  pm.max_requests = 500

To calculate the proper sizing of individual processes, you first need to determine the average size of PHP processes:

ps aux | grep php-fpm | awk '{sum+=$6} END {print "Average MB:", sum/NR/1024}'

For example, if we obtain a process size of 100 MB, we can calculate the number of processes based on the available RAM. Be careful not to overload the RAM; leave some margin to handle all other background processes.

Example with 16 GB RAM: Number of processes = RAM (MB) / Average Process Size (MB)

On a 16 GB RAM system, I usually allocate about 2 GB for background processes.

Number of processes → 14,000 / 100 = 140

min_spare_servers = 10%(140) = 14
max_spare_servers = 30%(140) = 40

  pm = dynamic
  pm.max_children = 140
  pm.start_servers = 28
  pm.max_requests = 500