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

Want to help support this blog? Try out Oh Dear, the best all-in-one monitoring tool for your entire website, co-founded by me (the guy that wrote this blogpost). Start with a 10-day trial, no strings attached.

We offer uptime monitoring, SSL checks, broken links checking, performance & cronjob monitoring, branded status pages & so much more. Try us out today!

Profile image of Mattias Geniar

Mattias Geniar, February 11, 2012

Follow me on Twitter as @mattiasgeniar

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.



Want to subscribe to the cron.weekly newsletter?

I write a weekly-ish newsletter on Linux, open source & webdevelopment called cron.weekly.

It features the latest news, guides & tutorials and new open source projects. You can sign up via email below.

No spam. Just some good, practical Linux & open source content.