Add ‘Options FollowSymLinks’ and avoid ‘Options SymLinksIfOwnerMatch’ in Apache to save disk I/O

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

Following up on the advice to stop using AllowOverride All in Apache configs, Wim Godden kindly reminded me of a similar issue that exists when not using FollowSymLinks or when using SymLinksOfOwnerMatch.

The bad configuration

It’s about the following kind of configuration.

<Directory "/var/www/html/mysite.be">
    Options SymLinksIfOwnerMatch -FollowSymLinks
</Directory>

The option FollowSymLinks should always be kept on if possible. Without that, every time you request a file, Apache will check if that file resides in a directory that is somehow symlinked. If it is, it will block your request. But that requires an extra check for every file being accessed.

If someone on the site would request the file “/content/styles/v3/style.css”, that would results in the following system calls:

stat("/var/www/html/mysite.be/content/styles/v3/style.css", {st_mode=S_IFREG|0644, st_size=5, ...}) = 0
lstat("/var/www/html/mysite.be/content", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
lstat("/var/www/html/mysite.be/content/styles", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
lstat("/var/www/html/mysite.be/content/styles/v3", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
lstat("/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

That’s 4x an lstat() disk I/O to check if any of the directories between “/var/www/html” and “/var/www/html/mysite.be/content/styles/v3” contain any symlinks.

The good configuration

Below is a better configuration. It does not check the symlinks if the owners match (-SymLinksIfOwnerMatch) and it does not limit the Apache server from following Symlinks (+FollowSymLinks).

<Directory "/var/www/html/mysite.be">
    Options -SymLinksIfOwnerMatch +FollowSymLinks
</Directory>

If I were to request a simple file “/content/styles/v3/style.css”, it would result in the following system calls:

stat("/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

That’s a lot less disk I/O on a busy server.



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.