Apache performance tuning
Apache is a popular web server. This article provides some configuration tips to improve performance when Apache is in use on a BitFolk VPS.
Do not run in swap!
One of the most important considerations when trying to increase Apache performance is avoiding use of swap for the Apache processes themselves.
Pick an appropriate number for MaxClients
The typical MPM in use is prefork, and the default value of MaxClients is 150. This is in most cases far too large for a VPS with limited RAM.
When you first install Apache everything may seem to work fine, and this may continue to be the case for a long time, but as soon you serve something popular the number of simultaneous client connections will increase until it reaches MaxClients. Take a look at how big your Apache child processes are:
$ ps -C apache2 -o user,pid,rss,command USER PID RSS COMMAND www-data 17350 18184 /usr/sbin/apache2 -k start www-data 17352 18588 /usr/sbin/apache2 -k start www-data 17537 19452 /usr/sbin/apache2 -k start www-data 19217 12544 /usr/sbin/apache2 -k start www-data 19219 18044 /usr/sbin/apache2 -k start www-data 19231 12084 /usr/sbin/apache2 -k start www-data 19232 16436 /usr/sbin/apache2 -k start www-data 26083 17980 /usr/sbin/apache2 -k start root 26409 728 /usr/sbin/apache2 -k start
In the above example the Apache child processes are about 18MiB in size (RSS). On a VPS with 240MiB of RAM, assuming nothing else were running, we might expect to be able to support 240/18=13.33 simultaneous connections before swap is used.
If the MaxClients were left at the default 150 and we put some popular content up then this might demand up to 150*18=2,700MiB of memory from the virtual memory subsystem. Very quickly this would hit swap, which would kill performance of all Apache children, leading to connections stacking up and users hitting reload, which creates more simultaneous connections. It should be easy to see how what seemed like a perfectly working configuration can bring your VPS to its knees as soon as it gets real web traffic.
If on the other hand the MaxClients had been limited to about 13, all Apache children together could only use about 234MiB of RAM. Under a flash crowd situation ("slashdot effect"), MaxClients simultaneous connections will be reached and subsequent requests will be queued until there is an Apache process available to serve them. Web clients will still experience large delays and your site may still appear to be down, but the difference is that your VPS itself will not be down.
In the above example, if you wanted to serve more than 13 simultaneous clients then you need to either increase your RAM or decrease the size of each Apache process. You cannot simply increase MaxClients beyond your available RAM and expect it to just work - as soon as you actually tried to have more processes running you'll hit swap and performance spirals downwards.
Decreasing the size of Apache processes
A major factor in how big each Apache process needs to be is how many modules you have loaded. On Debian and Ubuntu you can see which modules you have enabled as follows:
$ ls /etc/apache2/mods-enabled/*.load /etc/apache2/mods-enabled/alias.load /etc/apache2/mods-enabled/auth_basic.load /etc/apache2/mods-enabled/authn_file.load /etc/apache2/mods-enabled/authz_default.load /etc/apache2/mods-enabled/authz_groupfile.load /etc/apache2/mods-enabled/authz_host.load /etc/apache2/mods-enabled/authz_user.load /etc/apache2/mods-enabled/autoindex.load /etc/apache2/mods-enabled/cgi.load /etc/apache2/mods-enabled/deflate.load /etc/apache2/mods-enabled/dir.load /etc/apache2/mods-enabled/env.load /etc/apache2/mods-enabled/mime.load /etc/apache2/mods-enabled/negotiation.load /etc/apache2/mods-enabled/php5.load /etc/apache2/mods-enabled/reqtimeout.load /etc/apache2/mods-enabled/setenvif.load /etc/apache2/mods-enabled/status.load
Read the Apache documentation and see which of these modules you can disable. After disabling a module with a2dismod you can use apache2ctl configtest to check that your configuration still parses:
$ sudo a2dismod authz_host Module status disabled. Run '/etc/init.d/apache2 restart' to activate new configuration! $ sudo apache2ctl configtest Syntax error on line 12 of /etc/apache2/sites-enabled/000-default: Invalid command 'Order', perhaps misspelled or defined by a module not included in the server configuration Action 'configtest' failed. The Apache error log may have more information.
In the above example the configuration no longer parses because on line 12 of /etc/apache2/sites-enabled/000-default we have:
<Directory /var/www/> Options Indexes FollowSymLinks MultiViews AllowOverride None Order allow,deny allow from all </Directory>
This is a host-based access list (allow from all) and we just disabled the authz_host module, which is what implements those. Since this configuration currently allows access from everywhere, it needn't actually be there at all and could be commented out, allowing the server to load without the authz_host module.
Serve static content from a different daemon
From earlier discussion we established that there's a limit on how many simultaneous clients can be served, and that this limit was determined by how much RAM is available and how much memory each Apache process requires. You already know that you can reduce the size of the Apache process by disabling modules, but most interesting dynamic content tends to require large built-in interpreters like PHP or at least the CGI module.
You don't need multiple hosts or even multiple IP addresses to do this: if you keep all your static files in a given directory tree then you can reverse proxy that to another server listening on localhost and still get most of the benefit.
If you're seeing a lot of CPU usage or disk IO then you might want to consider the advice in the Apache Performance Tuning documentation about FollowSymlinks and AllowOverride.
Alternatives to Apache
Several simpler web servers are available which are more lightweight than Apache and therefore perform better under load, usually at the expense of Apache's highly flexible configuration.