Opinions on the best webserver configuration for Drupal vary from one user to the next. Thus, I set out to compare and document the performance of difference combinations of webserver options.

Experimental setup

I setup a Drupal 4.7 site with 2,000 users, 5,000 nodes, 5,000 path aliases, 10,000 comments and 250 vocabulary terms spread over 15 vocabularies. If you don't know what that means, you're probably not a Drupal user. That is OK. If you have basic technical knowledge of webservers the results might still be interesting.

Next, I configured the main page to show 10 nodes, enabled some blocks in both the left and the right sidebar, setup some primary links, and added a search function at the top of the page. I also setup a contact page using Drupal 4.7's contact module. The image below depicts how my final main page was configured.

Drupal.7 main page

Benchmarks were done on a 3 year old Pentium IV 3Ghz with 2 GB of RAM running Gentoo Linux. I used the following software: Apache 2.0.55, Lighttpd 1.3.16, PHP 4.4.2, PHP 5.1.4, and MySQL 4.1.4 without special configuration or tweaking other than strictly necessary to get things up an running.

Apache's ab2 was used to compute how many requests per second the above setup is capable of serving.

Drupal page caching?

Drupal has a page cache mechanism which stores dynamically generated web pages in the database. By caching a web page, Drupal does not have to create the page each time it is requested. Only pages requested by anonymous visitors (users that have not logged on) are cached. Once users have logged on, caching is disabled for them since the pages are personalized in various ways.

On some websites, like this weblog, everyone but me is an anonymous visitor, while on other websites there might be a good mix of both anonymous and authenticated visitors.

When presenting the benchmark results, I'll make a distinction between anonymous visitors and authenticated visitors. This allows you to interpret the results with the dynamics of your own Drupal websites in mind.


APC, which stands for Alternative PHP Cache, is a free PHP extension that will optimize the performance of PHP applications by caching PHP code in a compiled state.

Drupal.7 apc vs noapc

With APC, my configuration could serve 4 times as many pages to anonymous visitors, and 2 times as many pages to authenticated visitors.

PHP4 or PHP5?

The figure below depicts a comparison between PHP4 and PHP5. It shows that on average, PHP5 can handle 13% fewer requests per second than PHP4 for anonymous visitors, and 4% fewer requests for authenticated visitors.

Drupal.7 php4 vs php5

Reverse proxy?

When a proxy, like Squid, is configured as a reverse proxy it can act as a caching mechanism for web pages. Because the reverse proxy sits between the internet and the webserver, it can intercept all requests and respond to them by serving cached content. This reduces the load on the webserver (and the database).

I haven't setup a reverse proxy for these experiments because, currently, Drupal doesn't generate the proper HTTP headers to control the cache mechanism. Also, because of the way Drupal works, it is quite a challenge to setup and configure a reverse proxy.

The one scenario where it would be easy to setup, and likely to be beneficial, is where all visitors are anonymous visitors.

mod_php or FastCGI?

There are many ways to run PHP. FastCGI and mod_php are two of the most commonly used approaches. Most people are using mod_php because that is the default on nearly all Linux distributions. With mod_php, PHP runs as an Apache module and as a result, all PHP applications are executed with the privileges of Apache. This means that your Drupal files need to be readable (and sometimes writable) by Apache.

When using FastCGI, the web applications can run under different privileges than that of Apache. Hence, FastCGI is often used on shared hosts to provide additional security. Using FastCGI you can prevent that other users on the system, can read or write your files. The downside, however, is that FastCGI has an additional performance cost.

So when choosing between mod_php or FastCGI, you are making a trade-off between security and performance. The figure below shows the relative performance of the two approaches, and can help you understand the trade-off. When switching from mod_php to FastCGI we observe a 63% slowdown for anonymous visitors, and a 18% slowdown for authenticated visitors.

Drupal.7 fastcgi vs mod_php

Apache or Lighttpd?

Lighttpd (or Lighty) is a HTTP daemon designed for high-performance environments. Its goal is to be fast and have a small memory footprint. The figure below shows how Apache compares to Lighttpd.

Drupal.7 apache vs lighttpd


So what are the best and worst configurations of those i have tested? And what is the fastest configuration, while still being secure? Turns out that the slowest configuration is Apache 2 running PHP5 as an Apache module without using APC. Unfortunately, this is one of the most common configurations.

The fastest configuration using the more secure FastCGI method, on the other hand, is Lighttpd with PHP4 in FastCGI mode using APC. For anonymous visitors, the latter is almost 4 times faster than the former, while being more secure. This is illustrated by the figure below.

If you are not on a shared host, you might not care about the security options provided by FastCGI. In that case, the next and last figure might be of interest. Turns out that for anonymous visitors my fastest Apache configuration is 3% faster than the fastest Lighttpd configuration.

Drupal.7 slow vs fast


Frank (not verified):

I am interested in two figures missing from your very interesting article. Can you tell me what the difference between Apache + mod_php and Lighttpd + FastCGI are? Is the Lighty combination still faster?

BTW: thanks for testing this for us. :) We are still working on the "best" hosting package we can offer for Drupal sites, so if you have any ideas about that, let's have lunch some day.


I added the requested comparison to my blog entry. Does this buy me a free lunch? ;-)

Those who are in the hosting business might want to validate my results. As mentioned, no tweaking went into this other than what was strictly necessary to enable the functionality I was benchmarking. Depending on your tweaking-fu you might be able to get more out of the above configurations.

greggles (not verified):

I think I speak for lots of people when I say that this is very helpful.

It confirms some long held points (e.g. use a PHPCache) and also shows that the Drupal Cache mechanism works rather well already.

I promise to buy you lunch if you could add in a test of the "file based cache". Perhaps tapas at the DrupalCon2007 in Spain?

Gerhard Killesreiter (not verified):

Thanks, Dries, for doing these tests! All we need to do now is to install APC on drupal.org. :)

I am a bit confused why the relative gain for unauthenticated users is so much larger than for authenticated ones. I think that with some investigation we could maybe tweak this a bit.

Frank (not verified):


I think the main point is that 2 anonymous visitors will get (almost?) exectly the same page. It can thus be cached pretty efficiently.

Two authenticated users will get a different page. Different security/ACL checks will have to be performed, so you can't really cache those, so the cache hit rate is much and much lower.

Gerhard Killesreiter (not verified):

Not sure you are right about that. APC is supposed to cache the interpreted PHP code. The code is pretty much the same for each user. I am wondering if increasing the cache size might help.

Some quick testing on my own confirmed that you get a full cache hit if you access a page first as one and then as another logged in user.

Gerhard Killesreiter (not verified):

Dries, could you rerun your APC tests for anonymous and authenticated users and report back on the cache hit ratio? APC comes with a nice apc.php file which presents these statistics for you.


Bert, I haven't used different user IDs, different user roles or different sidebar confgurations. Whether that would have been more realistic depends on your website. The setup I used is a fairly accuracte model for this website, for example.

Scott (not verified):

Hi Dries,

AFAIK the FastCGI implementation on Apache is quite dated and Lighttpd has far better FastCGI support. It probably explains why in the test of Apache vs Lighty, Lighty is so much faster. In fact FastCGI is the only way to run PHP on Lighttpd.

How's PHP-FastCGI configured? Via TCP or unix socket? You'll find with socket you'll probably get around 5% more performance.

Also what's the parameters for ab2? Any concurrency test or just single threaded? It would be interesting to re-do all the tests with 20 concurrent clients hitting the same page at the same time.

Thanks for the info!

Matt Rae (not verified):

I haven't ever seen much difference using lighttpd vs apache+mod_fastcgi for running php applications. The bottleneck is going to be php using the cpu.

Serving static content is a different story :)

Kieran (not verified):

ab is not reliable for measuring because it measures connections not Drupal page loads. Drupal returns a DB connection failed page which ab treats as successful and therefore the results are skewed when loading Drupal.


Such errors would have been logged in Drupal's watchdog table. It is easy to see if something went wrong, or not.

Alan (not verified):

I've been messing about on a dreamhost dedicated server to figure out a 'best' configuration, so this analysis was very helpful, thanks. My current challenge is to see how much difference fast-cgi will make over regular cgi.

In my particular case (http://share.ca/), the site has a lot of pdfs, and when I look at the stats, in fact more than half the bandwidth is from pdfs. So a site like this would benefit more from a lighty or apache/fastcgi setup I think, since the mod_php wouldn't provide anything to the majority of the traffic (and would just contribute to memory and load, though I don't know how much).

On the other hand, perhaps a lot of that pdf traffic is from spiders during off hours, and may not have a lot of effect on the normal server load, and thus no noticeable effect on the typical user experience (since a typical user is probably not going to go around downloading all the pdfs...).

Conclusion - an analysis of your site traffic is probably a good idea before making any decisions about your setup, with the usual caveat about the reliability of any conclusion based on statistics.

ultraBoy (not verified):

Dries, could you please make some kind of a benchmark package, so we could download and install it? Running tests on different machines could help determine hardware requirements and bottle-necks for Drupal, and also which hardware and OS is better. For example: CPU (AMD or Intel architecture), memory size/speed, hdd type/speed and so on.

Ivan (not verified):

Would you please share with us how you configured ab to simulate logged-in users?

Thanks a lot! This is a very helpful article, it is crucial in deciding if Drupal is the right solution for any Web project.

Allie Micka (not verified):

I must raise objection to the "CGI is more secure than mod_php" assertion.

Under some implementations, there's no difference at all, and under most implementations, cgi - or fastcgi - is more secure for other customers on a shared hosting platform, but actually less secure for a site owner.

mod_php will serve requests using processes that have the permissions of the apache user. On a shared server, that apache user has read access to every site it's responsible for hosting. The concern with this is, if something on Site A is successful in exploiting PHP, it has the permissions to view (and possibly change) something on Site B. This is not good at all, but can largely be addresed through the use of private temp directories, open_basedir restrictions, and safe_mode.

By default, CGI behaves no differently: It still runs as the web use and therefore suffers from the same security problems. Plus, it's much slower because each request must re-launch another process in order to serve the request. However, most shared hosts wrap CGI processes with something like SuExec and/or suPHP.

Generally, SuExec/suPHP are configured to run as the user that owns the files. This frees you from the afore-mentioned vulnerabilities, because you can rely on unix permissions that prevent site A's scripts from viewing/changing site B. With this model, there's no one user who can view or change files across a client base.

That's great, but it usually means that Site A has full write access to all of its own files. So, while Site A can't reach out and touch Site B, it can be used to deface itself or change other aspects of its own operation (e.g. add a "email me a credit card number upon checkout" submit handler). Most hosting providers don't worry about this: as long as you can't mess up others' sites, that kind of trouble is your own fault for not patching.

The best solution is to use CGI + SuExec and two users for each site: one user who owns all the files, and another user that runs the CGI process. Most hosts don't do this, so I object to blanket statements about mod_php / cgi security.

I did some back-of-the-envelope testing myself, and was surprised to have similar results. mod_fcgid ( the successor to apache's fastcgi implemenation) appears to out-perform mod_php5 by roughly 10%

Plus, it's /way/ more secure :)

René L. (not verified):

I agree with the linux security geek about repeating your bechmarks with the current stable PHP version (5.2.3), considering the recently initiated GoPHP5 effort of Drupal and that Sebastian Bergmann benchmarked PHP 5.2 to be 3 times faster than PHP 4.4.
Even on my local Windows machine a fresh PHP 5.2.3 is 2 times faster than PHP 4.4.4:
# Run PHP 5 benchmark without extensions from command line
php -n bench.php
# Run PHP 4 benchmark without extensions from command line
cli\php -n bench.php