Stop using .htaccess files! No, really.
Tags: devops, performance, webperf
Published: 2020-02-14 22:26:32

---
title: Stop using .htaccess files! No, really.
published: true
date: 2016-11-24 04:43:00 UTC
tags: devops, performance, webperf
canonical_url: https://nystudio107.com/blog/stop-using-htaccess-files-no-really
---
# Stop using .htaccess files! No, really.

### Every CMS under the sun has you con­fig­ure a .htac­cess file if you’re using Apache. Don’t do it!

Andrew Welch / [nystudio107](https://nystudio107.com)

![997321 Code](https://nystudio107-ems2qegf7x6qiqq.netdna-ssl.com/img/blog/_1200x675_crop_center-center_82_line/997321-code.jpg)

Stop using <kbd>.htaccess</kbd> files! It seems like heresy. The <kbd>.htaccess</kbd> file has been a stan­dard part of the web­dev world for so long, it’s like an old friend. And yet, it’s time to say goodbye.

<kbd>.htaccess</kbd> files were born out of an era when shared host­ing was com­mon­place: sysad­mins need­ed a way to allow mul­ti­ple clients to access their serv­er under dif­fer­ent accounts, with dif­fer­ent con­fig­u­ra­tions for their web­sites. The <kbd>.htaccess</kbd> file allowed them to mod­i­fy how Apache works with­out hav­ing access to the entire server.

The Vir­tu­al Pri­vate Serv­er, or VPS, has made this a thing of the past. Excel­lent host­ing com­pa­nies like [Lin­ode](https://www.linode.com/), [Dig­i­tal Ocean](https://www.digitalocean.com/), [Vul­tr](https://www.vultr.com/), etc. give you an entire vir­tu­al­ized serv­er that is com­plete­ly insu­lat­ed and self-con­tained. And yet, like an appen­dix, <kbd>.htaccess</kbd> persists.

Indeed, mod­ern web servers such as [Nginx](https://www.nginx.com/) don’t even have the con­cept of a <kbd>.htaccess</kbd> file, because times have changed.

Why does it mat­ter, you say? In a word: **per­for­mance**. Don’t take my word for it, here’s what the [Apache Foun­da­tion](https://httpd.apache.org/docs/current/howto/htaccess.html) (the cre­ators of Apache) have to say:

<aside>
                                You should avoid using .htac­cess files com­plete­ly if you have access to httpd main serv­er con­fig file. Using .htac­cess files slows down your Apache http serv­er. Any direc­tive that you can include in a .htac­cess file is bet­ter set in a Direc­to­ry block, as it will have the same effect with bet­ter performance.
                            </aside>

The high­ly regard­ed [HTML5 Boil­er­plate](https://github.com/h5bp/server-configs-apache/blob/master/dist/.htaccess) warns against it as well:

<aside>
                                (!) Using ‘.htac­cess‘ files slows down Apache, there­fore, if you have access to the main serv­er con­fig­u­ra­tion file (which is usu­al­ly called <span></span>​<span>‘</span>httpd.conf‘), you should add this log­ic there.
                            </aside>

They even have an entire sec­tion on <kbd>apache.org</kbd> devot­ed to [When (not) to use .htac­cess files](https://httpd.apache.org/docs/current/howto/htaccess.html#when). In a nut­shell, if you are using <kbd>.htaccess</kbd> files, every sin­gle request the web­serv­er han­dles — even for the lowli­est <kbd>.png</kbd> or <kbd>.css</kbd> file — caus­es Apache to:

- Look for a <kbd>.htaccess</kbd> file in the direc­to­ry of the cur­rent request
- Then look for a <kbd>.htaccess</kbd> file in every direc­to­ry from there up to the serv­er root
- Coa­lesce all of these <kbd>.htaccess</kbd> files together
- Recon­fig­ure the web­serv­er using the new settings
- Final­ly, deliv­er the file

Every. Sin­gle. Request. And every web­page can gen­er­ate dozens of requests. This is over­head you don’t need, and what’s more, it’s com­plete­ly unnec­es­sary unless you are in an old-style shared host­ing envi­ron­ment (and if you are, stop read­ing this arti­cle and switch to a mod­ern VPS immediately).

The prob­lem gets worse the more things are added to the <kbd>.htaccess</kbd> file. Often it’s a dump­ing ground for things like rewrite rules and such, and the more com­plex your <kbd>.htaccess</kbd> file is, the more over­head is added when Apache has to parse it for every request.

_Tan­gent:_ A bet­ter solu­tion for 301 redi­rects is to have the CMS sys­tem process the redi­rects only after a 404 excep­tion has occurred, ala the [Retour](https://github.com/nystudio107/retour) plu­g­in for Craft CMS. The ratio­nale is that it’s bet­ter to have the web­serv­er be per­for­mant for the major­i­ty of nor­mal requests, rather than the excep­tion­al redi­rect requests. There are excep­tions, of course: the <kbd>http</kbd> → <kbd>https</kbd> redi­rect should always stay serv­er-side, because of how fre­quent­ly it occurs.

Here’s the default <kbd>.htaccess</kbd> file that ships with Craft CMS:

```

<IfModule mod_rewrite.c>
	RewriteEngine On

	# Send would-be 404 requests to Craft
	RewriteCond %{REQUEST_FILENAME} !-f
	RewriteCond %{REQUEST_FILENAME} !-d
	RewriteCond %{REQUEST_URI} !^/(favicon\.ico|apple-touch-icon.*\.png)$ [NC]
	RewriteRule (.+) index.php?p=$1 [QSA,L]
</IfModule>

```

Looks sim­ple enough. It’s just doing some fan­cy stuff to make sure you can have pret­ty look­ing URLs with­out <kbd>index.php</kbd> in them, and to make sure that 404 errors are rout­ed through Craft. This is pret­ty typ­i­cal of what many CMS sys­tems have you put into a <kbd>.htaccess</kbd> file.

For every domain on your web­serv­er, there is a Vir­tu­al Host file that tells the web­serv­er how to serve the web pages for that domain. All we need to do is trans­fer what we used to put in our <kbd>.htaccess</kbd> file into the Vir­tu­al Host file, and we’re done. It’s real­ly that easy.

Every­thing from your <kbd>http</kbd> -> <kbd>https</kbd> rewrite rules to expires head­ers, gzip com­pres­sion set­tings, and oth­er per­for­mance enhance­ment set­tings will all work too.

<aside>
                                If it worked in .htac­cess, it will work in your vir­tu­al host .conf file as well. Both are just ways to con­fig­ure your web­serv­er, but doing it once when the web­serv­er starts up vs. every request is more performant.
                            </aside>
## Git ​’Er Done

Since you’ve actu­al­ly read this far, I’ll assume you’re onboard with free­ing your­self from using <kbd>.htaccess</kbd> files. But how do we do it? Sim­ple. We just need to take the direc­tives that were in the <kbd>.htaccess</kbd> file, and put them in our Vir­tu­al Host <kbd>.conf</kbd> file. These files are usu­al­ly locat­ed in <kbd>/etc/httpd/conf.d</kbd> or <kbd>/etc/httpd/sites-available</kbd> on most Lin­ux distributions.

There is one oth­er small thing we must do as well. Even if we don’t even have a <kbd>.htaccess</kbd> file on our serv­er, Apache will still look for them if the <kbd>AllowOverride</kbd> direc­tive tells it to. So we just set <kbd>AllowOverride none</kbd> in our Vir­tu­al Host file, and that tells Apache that it does­n’t need to look for <kbd>.htaccess</kbd> files anymore.

Here’s what a com­plete Vir­tu­al Host <kbd>.conf</kbd> file looks like for Craft CMS. Oth­er CMS sys­tems should look pret­ty similar:

```

<VirtualHost *:80>
  ServerName BradsForMen.com
  ServerAlias *.BradsForMen.com
  DocumentRoot /var/www/BradsForMen/public
  CustomLog /var/log/httpd/BradsForMen.com-access.log combined
  ErrorLog /var/log/httpd/BradsForMen.com-error.log

## Canonical domain rewrite ##
  <If "%{HTTP_HOST} != 'BradsForMen.com'">
    Redirect "/" "http://BradsForMen.com/"
  </If>

  <Directory /var/www/BradsForMen>
      Options FollowSymLinks
      AllowOverride None

## Removes index.php from Craft URLs ##
      <IfModule mod_rewrite.c>
        RewriteEngine On
        # Send would-be 404 requests to Craft
        RewriteCond %{REQUEST_FILENAME} !-f
        RewriteCond %{REQUEST_FILENAME} !-d
        RewriteCond %{REQUEST_URI} !^/(favicon\.ico|apple-touch-icon.*\.png)$ [NC]
        RewriteRule ^(.+) /index.php?p=$1 [QSA,L]
      </IfModule>
  </Directory>
</VirtualHost>

```

Note that we sub­tly changed the regex from <kbd>RewriteRule (.+) index.php?p=$1 [QSA,L]</kbd> to <kbd>RewriteRule ^(.+) /index.php?p=$1 [QSA,L]</kbd>

That’s it. Save it, restart Apache with <kbd>sudo apachectl restart</kbd>, and away you go!

You may ask how much of a dif­fer­ence this makes. In truth, it’s not a huge gain. You can expect about a gain in the [sin­gle dig­its](http://www.fubra.com/blog/2008/01/07/htaccess-vs-httpdconf/), which will become a greater impact as [traf­fic increas­es](http://www.eschrade.com/page/why-you-should-not-use-htaccess-allowoverride-all-in-production/). How­ev­er, giv­en how com­plete­ly unnec­es­sary it is to use <kbd>.htaccess</kbd> files, there’s real­ly no rea­son not to imple­ment the best prac­tice of eschew­ing its use. 

Even seem­ing­ly small per­for­mance gains add up when imple­ment­ed together.

## Further Reading

_If you want to be notified about new articles, follow [nystudio107](https://twitter.com/nystudio107) on Twitter._

<small>Copyright ©2020 nystudio107. Designed by nystudio107</small>