Using HTTP Caching Headers to Exclude Assets from a CDN

http caching headers

Setting up a CDN comes in very useful for delivering your static assets faster amongst other things. The fact that your assets are cached across multiple PoPs in various locations means that visitors will experience less latency upon making a web request and you will benefit from improved redundancy, increased security, etc. However, depending upon the assets your site uses, you may not want to cache certain static files. Certain CDN integration options provide you with the ability to exclude specific files / directories but what if your CDN integration method doesn’t allow for this?

That is where HTTP caching headers come into play. These headers can be set at the origin server to define the caching behavior of a particular directory, file type, etc. This article will further explain the various types of caching headers as well as provide examples of how to exclude specific files from a CDN both using Nginx and Apache web servers.

Introduction to HTTP Caching Headers

The following list is a quick introduction to the HTTP Caching Headers available to web developers. To read more on this topic check out our HTTP Cache Headers – A Complete Guide article.

Cache-Control

Cache-Control is an HTTP caching header that allows you to specify a set of directives which determine when / how a response should be cached. Depending upon how these directives are set, the web browser will know whether to cache the response or not, the length of time the response should be cached for, etc. The following is a list of Cache-Control directives:

  • no-cache
  • no-store
  • public & private
  • max-age
  • s-maxage
  • no-transform

Pragma

Pragma is an old header which most newer systems now interpret as Cache-Control. There will be no new directives for the Pragma header, however, the one directive that may be of interest for excluding an asset from cache is the pragma: no-cache directive. Older implementations may still honour this header which is why it is sometimes included.

Expires

Expires is another HTTP caching header which can be used to define how long an asset should be cached for. Similarly to Pragma, this header was most popular in older browsers, however, it is still useful to include in the case that an old browser accesses your content. It’s important to note that the Cache-Control’s header directives max-age and s-maxage will take precedence over the Expires header in newer browsers.

Validators

Cache validators such as Last-Modified or ETag help the browser determine whether the asset has been modified since the last time it was accessed. In the case of ETag, the browser does so by defining an arbitrary token for every asset. Then, once the Expires or Cache-Control value has been met, the browser will check the server again to see if that asset has changed since the last time it was accessed. If the Etag on the server-side for that asset hasn’t changed, then the client will receive a 304 Not Modified status indicating that the asset hasn’t changed.

Exclude Specific Assets from Being Cached Using Nginx

If you’re an Nginx user, you can use the following snippet as an example of how to exclude a specific directory from being cached on the KeyCDN edge servers. Before starting the with configuration snippet, the “Ignore Cache-Control” must first be disabled within your KeyCDN zone’s advanced features.

ignore cache control disabled

Additionally, you must also set the Expires value to “0” so that KeyCDN will honor the Cache-Control header as received from the origin.

keycdn expires option

Once these options are properly configured, the CDN edge servers will honor the X-Accel-Expires, Cache-Control and Expires headers sent from the origin server. Now, using the following snippet will allow you to set any CSS or JS assets within the wp-content/themes directory to Cache-Control: no-cache.

location ~ /wp-content/themes/.*\.(js|css)$ {
add_header Cache-Control no-cache;
}

Therefore any CDN requests for such assets will return an X-Cache: MISS response header back to the client. However, all other assets outside of the wp-content/themes/ directory will continue to return an X-Cache: HIT from the CDN and will honor any Cache-Control directives defined by the origin server.

Additionally, to specify only a single asset to be excluded from the CDN you can use the following snippet.

location ~ genericons\.css {
 add_header Cache-Control no-cache;
 }

This tells the origin server to set the asset which uses the filename genericons.css to Cache-Control: no-cache. Therefore, since we have defined above that the CDN honors the origin server’s HTTP caching headers, only this file will return an X-Cache: MISS from the CDN.

Exclude Specific Assets from Being Cached Using Apache

Similarly for Apache users, the same CDN options must be configured to exclude specific assets from being cached by the CDN. Once the Ignore Cache-Control has been disabled, the Expires feature has been set to 0 and the changes have been saved and deployed, you can move on to defining a specific snippet in your .htaccess file.

Similar to the above snippets for Nginx, Apache users can implement various rules to avoid the CDN from caching certain files, directories, or file types. Apache users must ensure that the mod_headers module is installed and enabled, otherwise, custom HTTP headers won’t work.

The snippet below is used to exclude one file (in this case genericons.css) from being cached.

<FilesMatch "genericons\.css">
Header set Cache-Control "no-cache"
</FilesMatch>

Additionally, if there are particular file types that you want to exclude from being cached, you can define something like the following to exclude both PNG and XM files.

<FilesMatch "\.(png|xml)$">
Header set Cache-Control "no-cache"
</FilesMatch>

Because of the way .htaccess works, you can create multiple .htaccess files in different directories and the rules within a specific .htaccess file will only apply to that directory and its subdirectories. Therefore, if you want to exclude an entire directory from being cached, you can simply create a new .htaccess file and define the appropriate no-cache directive for your desired file types.

2 Comments

    1. Sebastian Krohn

      Images are usually cached nicely out of the box. you can confirm this by double checking the HTTP headers with curl or browser dev tools.

      Glassfish is a different scenario. If you are going to deliver Glassfish-generated content through KeyCDN (or any other) you’d want to set the Zone options as described in “Exclude Specific Assets” above so the origin server has full control over the caching and then tune your Glassfish servers caching configuration.
      A quick search gives this part of the documentation but there might be more to it:
      https://docs.oracle.com/cd/E19776-01/820-4496/6nfv5l551/index.html

Leave a Reply to Raphael Chaula Click here to cancel reply.