Skip to main content

Optimizing php-fpm the Promet Way

20 min read
Zakatell Kanda
By Zakatell Kanda
php-fpm logo

Ever wondered how you can tweak your server's configuration to get the most out of what you’re paying? Here are some good techniques that we like to use at Promet.

Disclaimer: This doesn’t mean that it’s the perfect server setup, but it’s a good start.  Every requirement is unique and understanding how it works is always the first step.  Having good documentation in the form of a blog post saves us a lot of time and effort so we would like to share our experience as well.

At Promet, we use nginx and php-fpm for our servers.  One good benefit of this against using the good old mod_php from apache is that nginx can act as a proxy and will serve the static files directly, only those with extension of php are passed to fpm-php.

Optimizing php-fpm is tricky at first but once you understand how it works then it’s quite a bit easier than you think. We are using debian base system so the default location of the the configuration file is /etc/php5/fpm/pool.d/www.conf.

 

Choosing the best strategy

There are three strategies on how php-fpm allocate memory: static, dynamic and on-demand.

  1. Static - a fixed number of a process you ask to allocate.
  2. Dynamic - allocate a fixed amount of processes but will dynamically increase once your load increases.
  3. On-demand - nothing will start as long as there are no requests to be served.

Choosing which type of strategy is quite confusing at first, but out of the three you should always use Dynamic and on-demand. This allows you to dynamically allocate memory for your web servers to efficiently manage your server resources.

We will be using on-demand strategy, which basically means that it would start or kill new process based on demand.  The advantage of this is the simplicity because you only need to determine one setting, “max_children,” and you can leave everything else as default.

Let’s take the following server specification as an example:

  • 2 CPU
  • 4GB RAM
  • 30GB SSD

For now we will be using the default values of the packages. We will calculate the optimal setting based on the usage of a process. So you first need to have some traffic.

 

Determining memory per child process

We need to determine how much memory per child process of php-fpm is using for calculating the final value. I use a script called ps_mem to get some statistics of my processes and memory.

  • # Download the script first
  • wget http://git.io/joLG
  • # and run it like this:
  • python ps_mem.py | grep php5
  • the output should give you something like this:
    • 1.8 GiB + 145.5 MiB =   1.9 GiB    php5-fpm (41)

 

This means php-fpm is using in total 1.9 GiB with 41 Processes. After converting the value in Megabyte, we will divide it by the number of processes. This will tell us: How much each child process (41) is consuming.

  • 1900 MiB/41 Processes = 46.34 MiB
  • 48.59MB memory / Processes
  • We can now calculate the number of process php-fpm can calculate via this simple formula:
  • max_children = (Total Number of Memory - 1000MB) / FPM Memory per Process
  • We reserved 1000MB for other process like mysql, nginx, etc.
  • max_children = (4000 MB - 1000 MB) / 48.59
  • max_children = 62.5

 

You can now set the pm.max_children to have maximum of 62.5.

 

Conclusion

And that’s it, folks! I hope this has been as informative to you as it is to us.  

As always, we love to hear any constructive criticism and how this would help everyone, please contact us if you think something can be improved.

Further reading: PHP Configuration Manual

Interested in learning more about tinkering with code?

Sign up for training.

Zakatell Kanda
By Zakatell Kanda

How may I assist you?