Sample Apache cache configuration

26 Feb 2009 by David Corvoysier
The Apache 2 web server can be configured to define a custom cache policy, allowing a fine-grained control over your web site content lifecycle in browser caches. This article provides a step-by-step simple configuration sample. The reader is invited to read first this other article presenting the HTTP 1.1 cache mechanisms.

Step 1: Activate expiration module

By default, Apache 2 doesn't insert any expiration header in served documents. This feature is provided by a specific module, mod_expires. Two operations are required to activate the feature: •    add mod_expires to the list of enabled modules,
a2enmod expires
•    add the ExpiresActive On directive to the site configuration.
NameVirtualHost *
<VirtualHost>
...
<Directory "/var/www/mysite">
ExpiresActive On
</Directory>
...
</VirtualHost>


Step 2: Define a default expiration policy

A default expiration policy that applies to all documents can be specified using the ExpiresDefault directive. I would recommend to define the default expiration period to a very short value, in order to avoid client browsers keeping forever in cache documents for which you forgot to provide an explicit expiration period (see next paragraphs).
NameVirtualHost *
<VirtualHost>
...
<Directory /var/www/mysite>
ExpiresActive On
ExpiresDefault "access plus 10 minutes"
</Directory>
...
</VirtualHost>


Step 3: Define an expiration date per document type

A specific expiration policy can be defined for each document type using the ExpiresByType directive. It is for instance possible to define an explicit expiration policy for HTML pages, javascript, images and json text files in order to control their lifetime in the browser cache, and avoid unnecessary validity checks from the client.
NameVirtualHost *
<VirtualHost>
...
<Directory /var/www/mysite>
ExpiresActive On
ExpiresDefault "access plus 10 minutes"
ExpiresByType text/html "access plus 1 day"
ExpiresByType text/javascript "access plus 1 day"
ExpiresByType text/x-json "access plus 1 day"

ExpiresByType image/gif "access plus 1 month"
ExpiresByType image/png "access plus 1 month"
ExpiresByType image/jpg "access plus 1 month"
</Directory>
...
</VirtualHost>

Note: The apache 2 web server uses the MIME-type to categorize documents. In order to have the proper directive applied to them, JSON text files must be sent as text/x-json documents.

Step 4: Mark session-specific documents as non-cacheable

Even if a large part of a specific site might be cacheable without disturbing the service, some specific documents are purely dynamic (like the results of a search query for instance) and must not be cached. Fortunately enough, it is allowed to define exceptions to the general expiration policy defined for a given file type, using file pattern matching with the FilesMatch directive. Thus, it is possible to specify that a Cache-Control header corresponding to "no-cache" be inserted for all files matching a given criteria, that can be based on a regular expression. The Header directive is used to insert specific Cache-control values. It is provided by the mod_header module, which is activated by default.
NameVirtualHost *
<VirtualHost>
...
<Directory /var/www/mysite>
ExpiresActive On
ExpiresDefault "access plus 10 minutes"
ExpiresByType text/html "access plus 1 day"
ExpiresByType text/javascript "access plus 1 day"
ExpiresByType text/x-json "access plus 1 day"

ExpiresByType image/gif "access plus 1 month"
ExpiresByType image/png "access plus 1 month"
ExpiresByType image/jpg "access plus 1 month"

<FilesMatch "searchResults.html">