Adjusting PHP-FPM for Performance + Low Memory

PHP-FPM has as a default configuration that uses more memory than necessary. It has spare php-fpm processes ready to go, taking up memory in case there is PHP code to process. While not a problem if you have tons of RAM, it can be an issue for low RAM VPS and if you are using aggressive page caching then it is memory being used unnecessarily that could be used by MariaDB MySQL or other critical processes. I always use nginx with PHP-FPM running PHP 7.0 so this tutorial explains how to tweak the configuration to use as little RAM as possible.

Adjusting PHP-FPM for Performance + Low Memory

Open your PHP-FPM configuration for PHP 7.0.

sudo nano /etc/php/7.0/fpm/pool.d/www.conf

Adjust the following values as shown below in red so they match, note the ; in front of pm.start_servers, pm.min_spare_servers and pm.max_spare_servers.

pm = ondemand means php-fpm child processes will only be spawned when necessary

pm.max_children is the maximum amount of child processes that are allowed, 50 is quite liberal but if you see max children exceeded in your log files, you should increase this value

pm.process_idle_timeout kills the child processes after they have been idle for 10 seconds

pm.max_requests sets the maximum number of php requests for each child process

pm = ondemand

; The number of child processes to be created when pm is set to 'static' and the
; maximum number of child processes when pm is set to 'dynamic' or 'ondemand'.
; This value sets the limit on the number of simultaneous requests that will be
; served. Equivalent to the ApacheMaxClients directive with mpm_prefork.
; Equivalent to the PHP_FCGI_CHILDREN environment variable in the original PHP
; CGI. The below defaults are based on a server without much resources. Don't
; forget to tweak pm.* to fit your needs.
; Note: Used when pm is set to 'static', 'dynamic' or 'ondemand'
; Note: This value is mandatory.
pm.max_children = 50

; The number of child processes created on startup.
; Note: Used only when pm is set to 'dynamic'
; Default Value: min_spare_servers + (max_spare_servers - min_spare_servers) / 2
;pm.start_servers = 2

; The desired minimum number of idle server processes.
; Note: Used only when pm is set to 'dynamic'
; Note: Mandatory when pm is set to 'dynamic'
;pm.min_spare_servers = 1

; The desired maximum number of idle server processes.
; Note: Used only when pm is set to 'dynamic'
; Note: Mandatory when pm is set to 'dynamic'
;pm.max_spare_servers = 3

; The number of seconds after which an idle process will be killed.
; Note: Used only when pm is set to 'ondemand'
; Default Value: 10s
pm.process_idle_timeout = 10s;

; The number of requests each child process should execute before respawning.
; This can be useful to work around memory leaks in 3rd party libraries. For
; endless request processing specify '0'. Equivalent to PHP_FCGI_MAX_REQUESTS.
; Default Value: 0
pm.max_requests = 500

Test the validity of your php-fpm configuration syntax

php-fpm7.0 -t

You should see that the configuration is valid

[22-Mar-2017 13:19:13] NOTICE: configuration file /etc/php/7.0/fpm/php-fpm.conf test is successful

Now you can restart php7.0-fpm

sudo service php7.0-fpm restart

You will find the amount of RAM used is considerably reduced now.