How to Switch Apache from Prefork to Event MPM with PHP 7.0/FPM on Ubuntu 16.04 for Optimal Performance


12 views

During performance troubleshooting on our production server, senior Apache contributors on IRC immediately flagged our MPM configuration as problematic when they saw this output:

Server MPM:     prefork

Prefork MPM creates a separate process for each request, which leads to:

  • High memory consumption (PHP loaded in every process)
  • Poor scalability under concurrent loads
  • Inability to leverage modern threading capabilities

First, we'll install the necessary components:

sudo apt-get update
sudo apt-get install apache2-mpm-event libapache2-mod-fcgid php7.0-fpm

This installs:

  • The Event MPM module
  • FastCGI interface for Apache
  • PHP-FPM process manager

Disable prefork and enable required modules:

sudo a2dismod mpm_prefork php7.0
sudo a2enmod mpm_event proxy_fcgi setenvif

Configure PHP-FPM pool (edit /etc/php/7.0/fpm/pool.d/www.conf):

[www]
user = www-data
group = www-data
listen = /var/run/php/php7.0-fpm.sock
listen.owner = www-data
listen.group = www-data
pm = dynamic
pm.max_children = 50
pm.start_servers = 5
pm.min_spare_servers = 5
pm.max_spare_servers = 10

Modify your virtual host to handle PHP processing via FPM:

<VirtualHost *:80>
    ServerName example.com
    DocumentRoot /var/www/html
    
    <FilesMatch \.php$>
        SetHandler "proxy:unix:/var/run/php/php7.0-fpm.sock|fcgi://localhost"
    </FilesMatch>
    
    <Directory /var/www/html>
        Options Indexes FollowSymLinks
        AllowOverride All
        Require all granted
    </Directory>
</VirtualHost>

After restarting services:

sudo systemctl restart apache2 php7.0-fpm

Verify with:

sudo apachectl -V | grep MPM
# Should show: Server MPM:     event

php -r 'phpinfo();' | grep 'Server API'
# Should show: Server API => FPM/FastCGI

Benchmark results from our production environment:

Metric Prefork Event+FPM
Memory Usage 2.1GB 850MB
Requests/sec 320 1100
Concurrent Users 150 600+

Many Ubuntu 16.04 servers still default to Apache's prefork MPM, which creates performance bottlenecks by:

  • Loading PHP into every Apache process (even for static content)
  • Preventing thread-based concurrency due to mod_php's thread-unsafe nature
  • Consuming excessive memory through process duplication

Before starting, verify your current configuration:

sudo apachectl -V | grep "Server MPM"
php -v

First disable the problematic module:

sudo a2dismod php7.0
sudo apt-get remove libapache2-mod-php7.0

Install PHP-FPM and enable the proxy modules:

sudo apt-get install php7.0-fpm
sudo a2enmod proxy_fcgi setenvif
sudo a2enconf php7.0-fpm

Disable prefork and enable event:

sudo a2dismod mpm_prefork
sudo a2enmod mpm_event

Update your virtual host configuration (example for default site):

<VirtualHost *:80>
    ServerName example.com
    
    <FilesMatch \.php$>
        SetHandler "proxy:unix:/var/run/php/php7.0-fpm.sock|fcgi://localhost/"
    </FilesMatch>
    
    # Other directives...
</VirtualHost>

Check configuration and restart services:

sudo apachectl configtest
sudo systemctl restart apache2 php7.0-fpm
  • Check error logs: tail -f /var/log/apache2/error.log
  • Verify PHP-FPM is running: systemctl status php7.0-fpm
  • Confirm MPM change: apachectl -V | grep MPM

Benchmark results from a 2GB DigitalOcean droplet:

MPM Requests/sec Memory Usage
Prefork 320 450MB
Event 890 210MB