Optimize Cache Headers
Setting the correct Cache Headers on your web server is often overlooked by many website owners. By making some small changes on your web server or web application, you can give 'hints' about what content can be cached, and for how long, helping to deliver an even better experience for your customers.
Controlling cache behaviour with HTTP headers
Your content can be cached at multiple levels between your website and your user. When you access a website on your browser,
the content could actually be returned by a cache:
- at the client's browser,
- at a proxy (shared) cache, or
- at a gateway cache (e.g. a content delivery network such as MetaCDN).
Caching is generally considered to be a 'good thing' as it can drastically speed up initial and subsequent access to your websites.
However care must be taken to ensure the right information is cached for an appropriate amount of time. Thankfully, the HTTP protocol
(versions 1.0 and 1.1) allows for headers to be set on responses to HTTP requests, which control how these intermediary caches store
assets from your website. Note that setting the below headers is simply good web practice, regardless of whether you are using a CDN
or not. When combined with a CDN such as MetaCDN, these settings give you fine grained control regarding what content is cached, and
for how long. Below is an example HTTP header that is returned when an asset on a web server is requested:
HTTP/1.1 200 OK
Date: Fri, 08 Feb 2013 03:32:00 GMT
Server: Apache/2.2.14 (Ubuntu)
Last-Modified: Fri, 27 Jul 2012 01:23:24 GMT
ETag: "680027-6493-4c5c58eed7b00"
Accept-Ranges: bytes
Content-Length: 25747
Cache-Control: max-age=86400, public
Content-Type: image/jpeg
The 'Expires' HTTP header
The Expires HTTP header signals to all caches how long the requested asset is fresh for. If this time has expired, the cache will check with your origin server to see if the asset has changed. Most caches support the Expires headers. However, when both the Cache-Control and Expires headers are present, Cache-Control takes precedence. As such, we recommend using the Cache-Control header (described next) rather than the Expires header.
The 'Cache-Control' HTTP header (recommended)
The Cache-Control header was introduced in HTTP 1.1 to address the many shortcomings of the Expires header. In nearly every instance, the Cache-Control header is recommended to use over the Expires header. The Cache-Control header allows you specify the maximum amount of time that an asset will be considered valid (relative to the time of the request) via the max-age parameter. It also allows you to specify whether the response should be considered cacheable (public) or not (private) by intermediary caches.
What happens if I don't set any caching headers?
When your web server returns files that do not have explicit freshness information (like a Cache-Control or Expires header), downstream caches may choose to estimate how fresh it is using other headers, such as the Last-Modified header. For example, if your response was last modified a week ago, a cache might decide to consider the response fresh for a day.
Consider adding a Cache-Control header; otherwise, it may be cached for longer or shorter than you'd like, or not at all.
What happens if I don't want my content cached?
Often you do not wish certain pages or files to be cached. For instance, a logged in section of your site, or a sensitive file. In these instances, it is possible to explicitly tell any caches (and CDNs) that these files should not be cached under any circumstances via the Content-Control header. A cache control header such as the one below would be appropriate in this instance:
Cache-Control: private, no-cache, no-store, proxy-revalidate, no-transform
In this instance we are instructing any downstream cache that the content is private, so no shared proxy (such as a CDN) can store it. The no-cache directive maintains freshness of the content by forcing any caches to submit the request to the origin server for validation before releasing a cached copy. The no-store directive instructs caches not to keep a copy of the content under any circumstances. The must-revalidate directive informs caches that they must honor any freshness information you give them about the content, and cannot serve stale content under any circumstances. The proxy-revalidate directive is equivalent to the must-revalidate directive, however it only applies to proxy caches.