If you have deployed a LEMP (Linux, NGINX, MySQL/MariaDB, and PHP) stack, then you are probably using FastCGI proxying within NGINX (as an HTTP server), for PHP processing. PHP-FPM (an acronym of FastCGI Process Manager) is a widely-used and high-performance alternative PHP FastCGI implementation.
Here are the useful guides on setting up LEMP Stack in Linux.
- How to Install LEMP Stack with PhpMyAdmin in Ubuntu 20.04
- How to Install LEMP Server on CentOS 8
- How to Install LEMP on Debian 10 Server
Recently, all our PHP websites on one of our LEMP web servers became slow and eventually stopped responding on logging into the server. we discovered that the system was running low on RAM: PHP-FPM had consumed most of the RAM, as indicated in the following screenshot (glances – system monitoring tool).
$ glances
In this article, we will show how to prevent PHP-FPM from consuming too much or all your system memory (RAM) in Linux. At the end of this guide, you will learn how to reduce PHP-FPM memory consumption by 50% or more.
Reduce PHP-FPM Memory Usage
After doing some research on the Internet, we discovered that we needed to reconfigure the PHP-FPM process manager and certain aspects of it to reduce PHP-FPM’s memory consumption in the pool configuration file.
The default pool is www and its configuration file is located at /etc/php-fpm.d/www.conf (on CentOS/RHEL/Fedora) or /etc/php/7.4/fpm/pool.d/www.conf (on Ubuntu/Debian/Mint).
$ sudo vim /etc/php-fpm.d/www.conf [On CentOS/RHEL/Fedora] $ sudo vim /etc/php/7.4/fpm/pool.d/www.conf [On Ubuntu/Debian/Mint]
Find the following directives and set their value to suit your use case. For directives that are commented out, you need to uncomment them.
pm = ondemand pm.max_children = 80 pm.process_idle_timeout = 10s pm.max_requests = 200
Let’s briefly explain the above directives and their values. The pm directive determines how the process manager will control the number of child processes. The default method is dynamic, which means the number of children (child processes) is set dynamically depending on some other directives including pm.max_children which defines the maximum number of children that can be alive at the same time.
The most ideal process manager is the ondemand scheme where no child processes are created at startup but are spawned on demand. Child processes are only forked when new requests will connect based on the pm.max_children and pm.process_idle_timeout which defines the number of seconds after which an idle process will be killed.
Last but not least, we need to set the pm.max_requests parameter which defines the number of requests each child process should execute before re-spawning. Note that this parameter can also be used as a workaround for memory leaks in 3rd party libraries.
Reference: A better way to run PHP-FPM.
After making these above configurations, I noticed RAM usage is now fine on our server. Do you have any thoughts to share related to this topic or questions? Reach us via the feedback form below.