Each user’s browser uses a built-in cache to store downloaded items, which can significantly speed up repeated visits to your site by loading from disk rather than network. How to set it up in Apache.
How does caching work?
The first time a user connects to your site, they download all the static resources required to render the page, including things like your logo. When they navigate to a new page, it will load your logo from memory rather than asking for it again, significantly speeding up performance and reducing the load on your web server during the process.
This is a client-side cache, but many sites will also use a Content Delivery Network, or CDN. A CDN is a network of servers located in front of your main web server or “origin”; server. This network caches your pages, increases your maximum bandwidth, reduces access latency and greatly reduces the voltage on your source server. If you want to learn more about CDNs, you can read our guide about them here.
Cache-Control is a title that you can configure your web server to add to all outgoing requests, which will tell your browser and CDNs how to cache your content.
Some pages should Never caches of shared caches as CDNs. Doing so risks exposing a user’s personal information to others. As a general rule, if the page will be exactly the same for all users, like your website, you can cache it. If it displays confidential user information, you will want to blacklist it from your cache. Static resources, such as CSS and images, can usually be cached for anyone, often much longer.
The amount of time spent on objects in the cache is also important. Called Time-To-Live (TTL), the maximum age of your cached resources determines how long the item will stay in cache before it is invalidated, and asks the user to request a new item. For static resources that do not change much, you can set very high TTL values, usually about two years. For things you might want to update, you may want to set lower TTL values to prevent inactive resources from being cached for too long.
You can always use versioned file names to trigger a cache load. If you are releasing a new version of a CSS style sheet, you can name it
styles-1.0.1.css, and the user’s browser (and any CDNs in front) will see it as a new file that needs to be downloaded again. Additionally, for some CDNs, you can issue manual invalidation statements to flush the existing cache without changing any file names.
How to use cache control in Apache
Cache-Control has some options:
public– Can be cached by anyone, including browsers and CDNs. Use this for most static objects.
private– Contains sensitive information that cannot be cached by CDNs or reverse proxies. The user’s browser can cache it locally. Use this for most authenticated pages.
no-cache– Despite the name, it does not disable caching. The browser can still cache the performance response but must check with the original server for updates before using it. Use this if you want the user to validate each time.
no-store– Disables caching completely. Use this only for very sensitive information that should not be sent twice.
In addition, you can add
no-transform directive, which deactivates all conversions that can be made to the resource. For example, some CDNs compress images to reduce bandwidth. This directive disables that behavior.
In Apache, you need to set this heading manually using
Header set Directive, which then:
Header set Cache-Control "max-age=84600, public"
max-age the value is set in seconds, for example,
max-age=300 for a five minute TTL, and
max-age=63072000 for two years.
You can put this directive at the root of your configuration to apply the entire site, but a better method is to apply the settings depending on the file type. For example, to set a high TTL for most static media, you can use one
Header set Cache-Control "max-age=63072000, public"
If you want to blacklist a specific path from the cache cache of CDNs, you can use a
<Directory "/private"> Header set Cache-Control "max-age=300, private" Directory>
Or simply match a single file:
"protected.html"> Header set Cache-Control "max-age=300, private" File>
The blocks with the more specific matches will take precedence over general regex matches, but you want to verify that everything is set correctly on the receiving end. You can check this from Chrome’s DevTools under Network> Headers.
If you only have access to
.htaccess configuration, you can still use directory matching by creating a new one
.htaccess file in each subdirectory.
Use Surrogate-Control to change CDN behavior immediately
Surrogate-Control header works just like
Cache-Control, but specifies specific instructions for CDNs and reverse proxies, rather than end users. This way, you can ask CDNs to do one thing, but send different directions to the browser.
You must set this heading manually, in the same way as you set it
Header set Surrogate-Control "max-age=300, public"
You definitely want to test with your CDN to verify that it works—
Surrogate-Control is fairly new and is not universal.