Avoid ‘AllowOverride All’ in Apache to limit disk I/O access

Mattias Geniar, Saturday, February 11, 2012 - last modified: Monday, October 1, 2012

Apache has an option called "AllowOverride" which allows you to override some Apache settings via a .htaccess file you can place in a directory. In it, you can override PHP settings, create URL rewrites, ... Pretty much the basics for every website. Most installation guides will tell you to always set "AllowOverride All" in your config, I'll show you why that's a very bad idea.

Consider the following simple Virtual Host configuration in Apache.

<VirtualHost *:80>
    ServerName mysite.be
    DocumentRoot /var/www/html/mysite.be
    <Directory "/var/www/html/mysite.be">
        AllowOverride All
    </Directory>
</VirtualHost>

Thats a simple site called "mysite.be" which gets its content from the directory "/var/www/html/mysite.be" on which the AllowOverride All directive is set. Because you allow overrides in the directory "/var/www/html/mysite.be", for each lower level file that is being accessed, Apache needs to check if the configuration is not being overwritten. So, if I were to call the URL "mysite.be/content/styles/v3/style.css" for a simple stylesheet, Apache would make the following system calls.

open("/var/www/html/mysite.be/content/styles/v3/style.css", {st_mode=S_IFREG|0644, st_size=5, ...}) = 0
open("/var/www/html/mysite.be/.htaccess", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
open("/var/www/html/mysite.be/content/.htaccess", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
open("/var/www/html/mysite.be/content/styles/.htaccess", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
open("/var/www/html/mysite.be/content/styles/v3/.htaccess", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
open("/var/www/html/mysite.be/content/styles/v3/style.css/.htaccess", O_RDONLY|O_CLOEXEC) = -1 ENOTDIR (Not a directory)
open("/var/www/html/mysite.be/content/styles/v3/style.css", O_RDONLY|O_CLOEXEC) = 10

Notice how in each directory between /var/www/html/mysite.be/ and /var/www/html/mysite.be/content/styles/v3/style.css/ an extra check is being made to verify if the .htaccess file exists there. That happens for every request made to the server, since Apache needs to continuously check if there is a new .htaccess file that may overwrite the config.

In comparison, if you don't enable AllowOverride All, there are a lot less system calls needed.

open("/var/www/html/mysite.be/content/styles/v3/style.css", {st_mode=S_IFREG|0644, st_size=5, ...}) = 0
open("/var/www/html/mysite.be/content/styles/v3/style.css", O_RDONLY|O_CLOEXEC) = 10

Instead of defining your Rewrites and other configurations in .htaccess file, consider placing them directly in your Apache configuration. On busy servers, this makes quite a difference in disk performance. And if you're about to start replacing your rewrite rules in Apache, why don't you take a second to consider Nginx as webserver instead of Apache.

If you're looking for more performance gains from Apache, have a look at the blogpost titled Add ‘Options FollowSymLinks’ and avoid ‘Options SymLinksIfOwnerMatch’ in Apache to save disk I/O which gives you about the same hints in I/O performance as this post.


Hi! My name is Mattias Geniar. I'm a Support Manager at Nucleus Hosting in Belgium, a general web geek, public speaker and podcaster. If you're interested in keeping up with me, have a look at my podcast and weekly newsletter below. For more updates, follow me on Twitter as @mattiasgeniar.

SysCast podcast

In the SysCast podcast I talk about Linux & open source projects, interview sysadmins or developers and discuss web-related technologies. A show by and for geeks!

cron.weekly newsletter

A weekly newsletter - delivered every Sunday - for Linux sysadmins and open source users. It helps keeps you informed about open source projects, Linux guides & tutorials and the latest news.

Share this post

Did you like this post? Will you help me share it on social media? Thanks!

Comments

Philip Paeps Monday, February 13, 2012 at 19:29

On most modern operating systems, this shouldn’t affect disk i/o much or at all. The kernel will cache the ENOENT after the first call to open() and return it immediately on subsequent calls. The only thing you’re potentially limiting is context switching (and on Linux with VDSO, even that is a negligible win).

Did you measure any significant reduction in i/o by enabling this? It would surprise me…

Reply


Jan Van Buggenhout Saturday, February 25, 2012 at 13:08

Philip: it does matter when your content is on a network-based filesystem (like for example NFS). And it did, as a matter of fact, have a measurable performance increase.

Reply


Leave a Reply

Your email address will not be published. Required fields are marked *

Inbound links