High Performance Drupal with Apache MPM Worker Threaded Server and PHP-FPM

In a previous article from over 5 years ago, we advocated the use of Apache MPM Worker Threaded Server with fcgid over Apache's mod_php.

That was for serveral reasons, including faster handling of static files by Apache threaded server, and lower memory utilization since PHP is not embedded in every Apache process.

However, there were some drawbacks, mainly that APC opcache cache is not shared, and each process has to have its own copy.

But we don't have to settle for the above trade off anymore, because there has been a better alternative for some time now: Apache MPM Worker Threaded server + PHP FPM. This configuration is part of PHP 5.3 and 5.5 available on Ubuntu 12.04 and 14.04.

PHP FPM uses the Fast CGI interface to the web server, and therefore can be used with other web servers, like nginx.

But, we stick to Apache, which has very good performance when it is in MPM Worker, since the threaded server is much more efficient and light weight than the Pre-Fork server.

In the sections below, we describe how to setup and tune Apache2 and PHP FPM optimally for both Ubuntu 12.04 and 14.04, since some sites will stay for some time on the former because of some incompatibilities of some modules with the latter. The former has Apache 2.2, while the latter has Apache 2.4. Because of this and other changes, the locations of the files are different, and some parameters are different too.

We assume a VPS of modest size, 1 or 2 GB of RAM. The values should be adjusted for larger servers of 8GB or more.

Apache MPM Worker Configuration

aptitude install apache2-mpm-worker apache2-threaded-dev apache2-utils libapache2-mod-fastcgi php5-fpm

We then configure Apache MPM Worker. Note that in Ubuntu 12.04, the configuration goes in /etc/apache/conf.d/mpm-worker.conf. As for Ubuntu 14.04, the file should be: /etc/apache2/conf-enabled/mpm-worker.conf.

<IfModule mpm_worker_module>
  ServerLimit           300
  StartServers            3
  MinSpareThreads         3
  MaxSpareThreads        10
  ThreadsPerChild        10
  MaxClients            300
  MaxRequestsPerChild  1000
</IfModule>

Then, we enable the required module for FastCGI to work:

sudo a2enmod fastcgi

Ubuntu 12.04 Configuration

On Ubuntu 12.04, it is better to stay with APC, rather than try with Zend OpCache. You can try running with Zend OpCache, but if you get segfaults, then stick with APC.

First, we tell Apache to send requests for files ending with .php to the PHP FPM server. This goes in the file: /etc/apache2/conf.d/php-fpm.conf, as follows:

<IfModule mod_fastcgi.c> 
  Alias /usr/sbin/php-fpm.fcgi /usr/sbin/php-fpm 
  AddHandler php-fastcgi .php 
  Action php-fastcgi /usr/sbin/php-fpm.fcgi 
  FastCGIExternalServer /usr/sbin/php-fpm -host 127.0.0.1:9000 -pass-header Authorization -idle-timeout 600
  <Directory /usr/sbin> 
    Options ExecCGI FollowSymLinks 
    SetHandler fastcgi-script 
    Order allow,deny 
    Allow from all 
  </Directory> 
</IfModule>

Then, in the file /etc/php5/fpm/pool.d/www.conf, you should have the following values, so that you do not exceed the available memory for the server:

[www]
user = www-data
group = www-data
chdir = /
listen = 127.0.0.1:9000
pm = dynamic
pm.max_children      = 10
pm.start_servers     = 4
pm.min_spare_servers = 2
pm.max_spare_servers = 6
pm.max_requests      = 2000

And finally we increase the memory for PHP and Zend OpCache from the default, in the file: /etc/php5/fpm/conf.d/local.ini.

For fairly simple sites with a small number of modules and themes (e.g. 100 or less), shm_size of 64MB is sufficient. For sites with a large number of modules (~200 or so), you will need to increase that to 128MB or more. Likewise, the value for memory_limit needs to increase for complex sites as well, perhaps up to 256MB in some cases.

To know exactly how much memory APC is using, you need to copy the apc.php file from /usr/share/doc/php temporarily to web root and access it from a browser.

; You may need to increase the values below, depending on your site's complexity
memory_limit = 96M
apc.shm_size = 64M

Ubuntu 14.04 LTS

For Ubuntu 14.04, you should not use APC, but rather the built Zend OpCache.

First, we tell Apache to send requests for files ending with .php to the PHP FPM server. This goes in the file /etc/apache2/conf-enabled/php-fpm.conf

<IfModule mod_fastcgi.c>
  Alias /php-fcgi /usr/lib/cgi-bin/php5
  AddHandler php .php
  Action php /php-fcgi
  FastCgiExternalServer /usr/lib/cgi-bin/php5 -host 127.0.0.1:9000 -pass-header Authorization -idle-timeout 600
  <Directory /usr/lib/cgi-bin>
    AllowOverride All
    Options +ExecCGI +FollowSymLinks
    Require all granted
  </Directory>
</IfModule>

Then we configure the maximum number of PHP processes that would provide good performance, but not exceed the server's memory. This goes in the file /etc/php5/fpm/pool.d/www.conf

[www]
user = www-data
group = www-data
chdir = /
listen = 127.0.0.1:9000
pm = dynamic
pm.max_children      = 10
pm.start_servers     = 4
pm.min_spare_servers = 2
pm.max_spare_servers = 6
pm.max_requests      = 2000

And finally we increase the memory for PHP and Zend OpCache from the default, in the file: /etc/php5/fpm/conf.d/local.ini.

For fairly simple sites with a small number of modules and themes (e.g. 100 or less), memory_consumption of 64MB is sufficient. For sites with a large number of modules (~200 or so), you will need to increase that to 128MB or more. Likewise, the value for memory_limit needs to increase for complex sites as well, perhaps up to 256MB in some cases.

To know exactly how much memory Zend OpCache is using, you need to get the opcache.php script from Rasmus Lerdorf's GitHub, and copy it temporarily to web root and access it from a browser.

; You may need to increase the values below, depending on your site's complexity
memory_limit = 96M
opcache.memory_consumption = 64M

Enabling Required Modules

The final step before restarting the servers is to enable the following Apache modules. This ensures that Apache, PHP-FPM and Drupal work properly together:

sudo a2enmod fastcgi actions rewrite deflate expires

Restarting

Now, restart Apache and PHP, so the above configurations take effect:

sudo service php5-fpm restart
sudo service apache2 restart

Now, you have a very performant yet light weight setup.

Contents: 

Tags: 

Comments

Benchmarks

Hello

Thank you very much for this article. Very well written with the whole process explained to set up this configuration. However, could you do some new and fresh benchmarks like you did in your previous article to compare this new solution against the one you suggested 5 years ago?

I will test it anyway and see how my Symfony2 apps react (under Ubuntu 14.04 with PostgreSQL 9.3).

Thanks in advance.

Elioty

Good

PostgreSQL is little used in the Drupal universe, but it is good that you will do benchmarks of any kind. Please share them here (at least mod_php vs. PHP-FPM).

I have been using it in production for many sites of all sizes, and it is fast.

My guess is that it will be as good as, if not better than, fcgid, with the added benefit of a shared op code cache, rather than one copy per process.

Thanks ...

Thanks, I fixed the typo.

What about files like

What about files like "malware.jpg.php" for Ubuntu 14.04 lts configured in php-fpm.conf? Looks like they come.

Not clear

Your question is not clear to me.

If you did find such file on your system, you should assume that your site has been compromised.

Varnish on top?

Thanks for the article, I used the old one as the basis of the deployment guide for our servers for the past few years and I quote it in the optimization section of our Ubuntu for Drupal instructions in Spanish at http://www.socinfo.com/ubuntu/configuracion -

What are your thoughts or experience on deploying Varnish on top of this config?
Mainly following the instructions at:
https://www.digitalocean.com/community/tutorials/how-to-speed-up-your-drupal-7-website-with-varnish-4-on-ubuntu-14-04-and-debian-7

Thanks in advance for any comment or hint.

uploadprogress

Thanks for the instruction, works great!

For Drupal 7, One thing is the uploadprogress now seems not able to work after switch.

In the status report page, it says:

"Your server is not capable of displaying file upload progress. File upload progress requires PHP be run with mod_php and not as FastCGI."

Do you have a workaround ?

THank you.

help!

Hi

I tried to follow your tutorial on 12.04 but now my system is completely unworkable and i think i am going to have to reinstall the entire system!!

I have tried to remove apache2 and reinstall and remove php-fpm so that I can just be back where i was but i fear that my system is now lost...any advice?

If you follow this tutorial you may have mpm install issues, you probably wont have

/etc/apache/conf.d/mpm-worker.conf

the folder on 12.04 is apache2 but it wont have mpm-worker.conf in it.

What are the errors you get?

You don't need to reinstall the system. You just need to uninstall apache2, all php packages, then remove /etc/php5 and /etc/apache2 and install them again.

But, what error messages are you seeing?

Here is what in /etc/apache2/conf.d/mpm-worker.conf on one of my 12.04 servers:

<IfModule mpm_worker_module>
  ServerLimit            30
  StartServers            3
  MinSpareThreads         3
  MaxSpareThreads        10
  ThreadsPerChild        10
  MaxClients            300
  MaxRequestsPerChild  1000
</IfModule>

Hi All, Have a drupal site of

Hi All,

Have a drupal site of mine which is been running slow and did check most of that is mentioned in here and still its not performing as it should be. Meanwhile did see a suggestion on using Apachebooster, did any one in this group has tried their hands on it. Need your suggestion.

Thanks

Diagnosis first, then treatment

You should not try something just because someone advertized it, or someone else said it has improved their performance.

The issue(s) may be in the database, Drupal code, network or any other component.

What you should do is first diagnose the problem, then find a treatment based on what the cause is.

If you want, we can diagnose and solve the problem for you. Click on the Contact link on the top right of this page.