Apache tuning


First check the MPM (Multi-Processing Module) used, most distributions come with a default prefork configuration where a minimum number of Apache processes is started (preforked) and more are added depending on incoming traffic. In general Apache optimization is about monitoring the number of Apache processes(also called workers) in combination with the total memory used by the system. Real time monitoring how many workers are in use and what they are doing is easy after installing and configuring the Apache mod_status module.

We advise you enable server-status monitoring, calculate the number of memory needed by your typical workload and optimize and constantly monitor processes/workers used by your Apache installation.

Step 1: Enable server-status module and check the server-status

Example status-page at Apache.org http://www.apache.org/server-status

If you see very few inactive workers (represented by “.” characters) you want to increase the appropriate configuration directive depending on Apache version and the MPM used.


Step 2: Check what mode Apache is running in

Apache can use a number of ways to handle requests. Apache calls this MPM (Multi-Processing Module) and there are several to choose from. By far the most widely used (at least on *nix platforms) are the three main ones: prefork, worker, and event. Essentially, they represent the evolution of the Apache web server, and the different ways that the server has been built to handle HTTP requests within the computing constraints of the time over its long (in software terms) history.

Prefork or mpm_prefork is compatible with everything including (simple) PHP and SSL and is easier to debug but not so kind on RAM usage if you have a lot of concurrent requests. For now we prefer to use mpm_prefork and enough free memory and keep a number of free workers to handle all http clients (both webacess/webapp and Z-push devices) at the same time.

sudo apache2 -V | grep -A 2 'MPM:'

or CentOS/RedHat and openSUSE/SLES will use httpd or httpd2

sudo httpd -V | grep -A 2 'MPM:'

Output should be like this:

Server MPM:     Prefork
  threaded:     no
    forked:     yes (variable process count)


Some installations can report the ITK MPM like:

sudo apache2 -V | grep -A 2 'MPM:'
Server MPM:     ITK
  threaded:     no
    forked:     yes (variable process count)

mpm_itk (see http://mpm-itk.sesse.net/) mpm-itk is based on the traditional prefork MPM, which means it’s non-threaded. This means you can run non-thread-aware code (like many PHP extensions) without problems. You lose out to any performance benefit you’d get with threads. You will also take an additional performance hit over prefork, since there’s an extra fork per request.

mpm_worker uses threading which is a big help for concurrency. A worker spins off some child processes, which in turn spin off child threads; some spare threads are kept ready if possible, to service incoming connections. This approach is kinder on RAM, since the thread count doesn’t have a direct bearing on memory use like the server count does in prefork. It also handles concurrency much more easily, since the connections just need to wait for a free thread (which is usually available) instead of a spare server in prefork. If you have the RAM available and start enough spare workers processes then the advantages of mpm_worker are limited.

Step 3: Measure and calculate maximum memory usage

Investigate the current memory usage of Apache using one liner scripts. Take these measurements for systems that have been running for a few days to get an accurate measurement for the distribution of web and z-push users. After measuring the individual average, calculate to total memory needed based on the number of devices and concurrent web sessions.

ps -ylC apache2 | awk '{x += $8;y += 1} END {print "Apache Memory Usage (MB): "x/1024; print "Average Proccess Size (MB): "x/((y-1)*1024)}'

or CentOS/RedHat and openSUSE/SLES will use httpd or httpd2

ps -ylC httpd | awk '{x += $8;y += 1} END {print "Apache Memory Usage (MB): "x/1024; print "Average Proccess Size (MB): "x/((y-1)*1024)}'

Alternative for a more detailed look on all memory consumed by any process if you intend to run zarafa-server and MySQL on the same host use this script:https://github.com/pixelb/scripts/blob/master/scripts/ps_mem.py

Step 4: Increase memory of the system and change settings

In this example we limit the total number of concurrent connection to 512 by adding the ServerLimit directive in the IfModle mpm_prefork setting. The ServerLimit in Apache version 2.2 is set by default on 256 if you need more then 256 concurrent workers you need to increase both MaxClients and ServerLimit but keep them equal if you go over 256 seehttp://httpd.apache.org/docs/2.2/mod/mpm_common.html#maxclients and http://httpd.apache.org/docs/2.2/mod/mpm_common.html#serverlimit.

NOTE 1 Setting the MinSpareServers and the MaxSpareServers parameter to a large number is almost always a bad idea because the added overhead of shutting down or starting spare(free) workers for background see http://httpd.apache.org/docs/2.2/mod/prefork.html#minspareservers and http://httpd.apache.org/docs/2.2/mod/prefork.html#maxspareservers

In the /etc/apache2/apache2.conf or /etc/httpd/httpd.conf update.

<IfModule mpm_prefork_module>
    StartServers          50
    MinSpareServers       25
    MaxSpareServers       50
    ServerLimit           512
    MaxClients            512
    MaxRequestsPerChild   10000

NOTE 2 Do a full restart of your Apache server NOT a reload because not all changes can be done without completely shutting down the Apache mother process.

Step 5: Enable monitoring of the server-status page and plot some nice graphs

Because workloads change you need to continuously monitor the number of idle Apache processes and the memory/swap usage of your setup. Please use this Nagios plugin and complement your monitoring by using a project like Munin.

Monitoring and graphing for Nagios


Additional graphing using Munin

sudo apt-get  --no-install-recommends install munin-common munin-node munin-plugins-extra libcache-cache-perl

To be able to use the Munin MySQL measurement plugins, install the package libcache-cache-perl.

Check to see which plugins need additional settings like apache-status do a:

sudo /usr/sbin/munin-node-configure --suggest

Enable the new plugins and reload the munin node:

sudo /usr/sbin/munin-node-configure --shell | sudo sh -x
sudo /etc/init.d/munin-node reload


TIP: On the munin-node

hostname -f

must result result in the same full name as used in the vonfig of the munin server.




Optional further testing and/or benchmarking

apt-get install httperf
httperf --hog --server=www --num-conns=100 --rate=10 --timeout=5

Share your thoughts with us!!!

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s