You are here

Part II: Apache

One of the challenges with Apache is to find the right number of threads to match your workload and at the same time not use up the servers memory. If you server is configured with to many threads it may start to use swap space to keep up with requests and you should see a drastically drop in response times. But before looking at threads you will need to enable/disable basic modules to ensure better performances.

Apache modules

I assume that you have activated mod_rewrite to get clean URLs running, but have you enabled mod_expires? This module handles HTTP expire headers which is used to set browser cache-control headers. Drupal's default htaccess file will make sure that static content (images, CSS, etc.) have a default two week expire header, which will give a performance boots by utilizing browser cache.

To enable the module run these commands on the server.

~$ a2enmod expires
~$ /etc/init.d/apache2 reload

Another module that might be worth a close look is mod_pagespeed, which is developed by Google. I have not my self used it yet, but thinks it's worth mentioning (See Drupal documentation for more information about this module).

You should look through the enabled modules and disable all modules not required by your site as they will system resources from each Apache process. Look in /etc/apache2/mods-enabled and at the Apache module list to figure out what you don't need to have enabled.

Here the authentication and index modules are disabled as I don't use them on my own servers.

~$ a2dismod auth_basic mod_authn_file autoindex


Configuring the number of clients and threads that Apache is allowed to spawn will determine the maximum number of simultaneous requests that the server can handle and the amount of memory used by Apache.


This setting determines the maximum number of child processes that can be spawned at any time. If there are more requests then processes to handle them the requests will be queued (maybe even timeout) and if the number of processes is to large there may not be sufficient memory on the system and swapping will kill your performance.

The magical number is the amount of available memory divided with the average size of your Apache child processes. Remember that we will need memory for other parts of the system as well, so you may need to come back and recalculate this number later on.

MaxClients = Memory / Child size

To find the average memory used by your Apache child processes this awk script below can be useful. This will only make yield a useable result on a running server which is handling requests. If you don't have a running server you should be safe guessing about 60-70 Mb, but this is very dependent on the number of Drupal modules and which modules you are using.

Simply create a file called memory.awk with the script below.

#/usr/bin/env awk
    count[NR] = $0;
    if (min == "") {
        min = max = $0
    if ($0 > max) {
        max = $0
    if ($0 < min) {
        min = $0
    print "Processes: ", length(count);
    if (NR % 2) {
        print "Median: ", count[(NR + 1) / 2], "\r";
    } else {
        print "Median: ", (count[(NR / 2)] + count[(NR / 2) + 1]) / 2.0, "\r";
    print "Max:", max, "\r";
    print "Min:", min;

Run this command to feed the awk script with information about the currently running Apache processes.

~$ ps -o rss -C apache2 --sort:rss --no-headers | awk -f memory.awk

You should get a result like this, where the memory used in Kb is shown. You may need to run the script more than once to get a better picture of the usages.

Processes: 152
Median: 64976
Max: 78684
Min: 7440

If I have 2 Gb of memory available to run the Apache processes that would yield 31 MaxClients with a process size of 64.9 Mb as discovered above.

2048 / 65 = 31.5

Note: If you need more than 256 MaxClients you have to increase the ServerLimit setting as well, it defaults to 256 connections. Again remember to have enough free memory for the other optimisations and caches mentioned in this article, so return and adjust MaxClients.

Max Requests Per Child and Keep Alive

The MaxRequestsPerChild setting sets a limit no the number of request a child process can handle before it dies. It can be set to a value of a few thousands to prevent memory leaks on busy servers.

KeepAlive should be turned on so that each TCP connection can be used to send more than one request and thereby remove the overhead of establishing new connections for each request. The KeepAliveTimeout should be set to 2-4 seconds so the server does not wait to long for the client to send another request and thereby ties up resources.

Htaccess files

One of the expensive parts of running Apache is the lookup for htaccess files in the file system. So moving those into your Apache configuration and disable by setting allow override to none can also improve performance.

PHP-FPM (Not completed)

You should start by installing PHP-FPM as described here.....

~$ apt-get install libapache2-mod-fastcgi
~$ a2enmod actions fastcgi alias
~$ /etc/init.d/apache2 restart
<IfModule mod_fastcgi.c>
  AddHandler php5-fcgi .php
  Action php5-fcgi /php5-fcgi
  Alias /php5-fcgi /usr/lib/cgi-bin/php5-fcgi
  FastCgiExternalServer /usr/lib/cgi-bin/php5-fcgi -host -pass-header Authorization

Read more

For more information about getting Apache to run faster you should really read Configuring Apache for Maximum Performance from 2006, it still has many valid points.


Add new comment

Plain text

  • No HTML tags allowed.
  • Web page addresses and e-mail addresses turn into links automatically.
  • Lines and paragraphs break automatically.