Apache – setting header expires via apache config

html header expires

Setting html header expires can help speed up your website. They work by telling your browser to cache various elements of a webpage for a period of time. These include scripts, images, css & so forth. So if you use the same stylesheet throughout the whole of your website, you can specify how long the cached version stays valid. This reduces the number of http requests made to your server thus reducing the overall time it takes to load your page.

Lets get started

Important note: If you are already specifying a header expire directly in your web page, ie html or php files, apache mod_expires will obey these rules and will not supersede them. Just to bear in mind just in-case you think the mod_expires is not working for you.

How do you know if expires are being set?

To check by default, analyse the response header sent to your browser by your server. I use Firefox, Firebug & the YSlow plugin to view page headers:

HTTP/1.1 200 OK
Date: Sat, 02 Mar 2013 20:12:00 GMT
Server: Apache/2.2.22 (Ubuntu)
Last-Modified: Sat, 02 Mar 2013 19:53:12 GMT
Cache-Control: max-age=86400
Expires: Sun, 03 Mar 2013 20:12:00 GMT
Content-Type: text/html

You will see an “Expires” field in your header. As you can see, this particular page was initially fetched on 02 Mar 2013 20:12:00 GMT and Expires on 03 Mar 2013 20:12:00 GMT

This is approximately 1 day , defined by Cache-control: max-age=86400 (86400 is seconds)

Hopefully, you too at the end of this tutorial will see the Expire field in your header.

Prerequisites

Ensure mod_expires is enabled. There are many google tutorials out there specific to your setup, in my setup I use a debian based server (ubuntu), you can use this command to enable mod_expires for apache:

sudo a2enmod expires

 

Enable & Setup expires

Edit your websites apache conf file. For instance

sudo nano /etc/apache2/sites-available/yoursite.com

Example apache config:

<VirtualHost *:80>

        ServerName www.yoursite.com
        DocumentRoot /var/www/yoursite

        <Directory /var/www/yoursite/>
                Options Indexes FollowSymLinks MultiViews
                AllowOverride All
                Order allow,deny
                allow from all
        </Directory>
</VirtualHost>

Add the following line to enable expires for your site:

ExpiresActive On

Your config should now look like this:

<VirtualHost *:80>

        ServerName www.yoursite.com
        DocumentRoot /var/www/yoursite

        <Directory /var/www/yoursite/>
                Options Indexes FollowSymLinks MultiViews
                AllowOverride All
                Order allow,deny
                allow from all

                ExpiresActive On
        </Directory>
</VirtualHost>

This tells apache to enable expires for your site – but we are not done! Now we want apache to tell the web browsers that we want to cache the page being served for a specified period of time. To do this we simply use the following directive:

ExpiresDefault "access plus 1 day"

ExpiresDefault will enable caching for all the static content served by the server

Your config should now look like this:

<VirtualHost *:80>

        ServerName www.yoursite.com
        DocumentRoot /var/www/yoursite

        <Directory /var/www/yoursite/>
                Options Indexes FollowSymLinks MultiViews
                AllowOverride All
                Order allow,deny
                allow from all

                ExpiresActive On
                ExpiresDefault "access plus 1 day"
        </Directory>
</VirtualHost>

Reload your apache configs or restart apache server:

sudo service apache2 reload

or

sudo service apache2 restart

Once apache has reloaded configs or restarted, browse to your website using Firefox, open the YSlow plugin via Firebug and click “Run Test.

Once the test has been completed, within YSlow click on the tab “Components” to view if Expires have been set:

 

 

 

 

If you look at the Expires column, you can see that the Server has sent a header with the Expires field set to 1-day. This tells the browser not to download these files again until they have expired after a day.

Setting Expires for specific content

In most cases you do not want to set the same Expires period for all your static content. For example, website graphics are unlikely to change in one day – so you may want to drill down and specifically tell the browser not to fetch new images unless 30 days have passed. You can do this very easily by utilising ExpiresByType directive. This lets you target a specific mime type, for example, you want to set Expires for jpeg/jpg images only for 30 days:

ExpiresByType images/jpg "access plus 30 days"
ExpiresByType images/jpeg "access plus 30 days"

However this can be problematic because a the file itself may change, i.e you had to update the logo. If you set expires to 30 days, the user will not see the new logo unless they clear their browsers cache or use CTRL+F5 to refresh all the content manually.

In this instance you will want to use the “modification” setting instead of “access”:

ExpiresByType images/jpg "modification plus 30 days"
ExpiresByType images/jpeg "modification plus 30 days"

This will tell the browser not to download the Logo unless 30 days have expired OR the Logo file was modified.

If you do not want to manually create ExpiresByType directive for each file type, you can group them instead using apache’s powerful <filesmatch> regex directive:

<filesMatch ".(ico|pdf|flv|jpg|jpeg|png|gif|js|css|swf)$">
        ExpiresActive On
        ExpiresDefault "access plus 1 day"
</filesMatch>

With this in place, apache will only enable and set Expires for the files matched.  You can also use this method to disable ExpiresActive for various types if you have set it globally.

See below for a complete apache config that I use on my developer server that works:

<VirtualHost *:80>

        ServerName www.yoursite.com
        DocumentRoot /var/www/yoursite

        <Directory /var/www/yoursite/>
                Options Indexes FollowSymLinks MultiViews
                AllowOverride All
                Order allow,deny
                allow from all

                ExpiresActive On
                ExpiresDefault "access plus 1 day"

                <filesMatch ".(ico|jpg|jpeg|png|gif)$">
                        ExpiresActive On
                        ExpiresDefault "access plus 30 day"
                </filesMatch>
                 <FilesMatch ".(txt|xml|js|css)$">
                        ExpiresActive On
                        ExpiresDefault "access plus 1 day"
                 </FilesMatch>

        </Directory>
</VirtualHost>

For more information about using mod_expires, please visit http://httpd.apache.org/docs/2.2/mod/mod_expires.html

Happy Caching!

One comment

Leave a Reply

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

This site uses Akismet to reduce spam. Learn how your comment data is processed.