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 the Apache process
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:
9 <Directory /var/www/> 10 Options Indexes FollowSymLinks MultiViews 11 AllowOverride None 12 Order allow,deny 13 allow from all 14 </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.
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.