Caching is useful for files on a web server that very rarely change. Images, pdf files and other content can be cached, reducing the network traffic between the server, the client, and the HTTP proxies in between them.
A common missunderstanding in HTTP caching is that content is only cached in the browser. This is not true, ISPs and network administrators may use a proxy that caches static files, delivering them much quicker to the clients. from a node closer in the network.
In this tutorial you'll find out how to do efficient caching using the Apache .htaccess file. This method should be preferred to using directives inside the HTML <head> tag, because proxies do not take them into account. Instead, they rely on HTTP headers, which you can easily set in .htaccess.
For more ways to speed up your site, see also How to speed up your site using .htaccess .
To be able to use the tips in this tutorial, your Apache installation should allow you to use .htaccess files, and you should have a basic idea of how HTTP headers work.
You will also need the mod_headers module. To make sure it's enabled, you can do it with:
The entire .htaccess file
Let's take a look at the entire htaccess config file, then go through all the configuration options.
Header unset Pragma FileETag None Header unset ETag # cache images/pdf docs for 10 days <FilesMatch "\.(ico|pdf|jpg|jpeg|png|gif)$"> Header set Cache-Control "max-age=864000, public, must-revalidate" Header unset Last-Modified </FilesMatch> # cache html/htm/xml/txt diles for 2 days <FilesMatch "\.(html|htm|xml|txt|xsl)$"> Header set Cache-Control "max-age=7200, must-revalidate" </FilesMatch>
Disabiling some of the headers
First, we unset the Pragma value from the server response headers.
Header unset Pragma
This will unset any headers that are created, by, for instance, a php script interpreted during the request. This is needed because browsers may interpret "Pragma: no-cache" as "This content is not to be cached". Then, we turn off the ETags:
FileETag None Header unset ETag
ETags are a mechanism to determine the origin of the content on the server (such as inode location), providing the browser information to cache objects depending on where they are on the disk. Disabling them not only makes the server work faster, but also allows the browser to rely on the Cache-Control headers, which we will describe next...
Adding static content cache headers
Next we will enable caching for different type of files.
For image files and pdf documents, in this example we set the cache to 10 days (that is 864000 seconds):
<FilesMatch "\.(ico|pdf|jpg|jpeg|png|gif)$"> Header set Cache-Control "max-age=864000, public, must-revalidate" Header unset Last-Modified </FilesMatch>
The "max-age" value indicates the time difference (in seconds) after which the content will be expired and reloaded from the server. The "public" keyword presence indicates that any system along the route may cache the response. The "must-revalidate" indicates caching systems to obey other header information you may provide at a later time about the cache. This should help preventing stale caching (that is, caching that delivers content that is outdated).
You will notice that we also unset the Last-Modified header. Why are we doing this? Because by eliminating the Last-Modified and ETags headers, you are eliminating validation requests, leading to a decreased response time. This should work fine in most cases when dealing with static, rarely updated content.
Caching files that change more often
<FilesMatch "\.(html|htm|xml|txt|xsl)$"> Header set Cache-Control "max-age=7200, must-revalidate" </FilesMatch>
For html, htm, xml, txt, xsl files that we expect are more likely to change, we won't eliminate the Last-Modified header, thus allowing cache systems to verify the last modification date of the document. In case the http document is fresher then the local cached version, the cache will be invalidated.
This was a quick overview of a cache setup for your Apache website. Comments, thoughts, mistakes, additions? Feel free to go ahead and edit the content of the tutorial, or open a new discussion thread.