A while ago I wrote an article about using Amazon S3 to serve images for my site, cocktailsrus.com. One thing I hadn’t noticed – until it was pointed out by my colleague, Richard Howells, who is very hot on caching and efficiency in general – was that the images were not being served with an expiry header to set client-side caching. That leads to two questions: why should I care, and what do I do about it?
1. Why should I care?
If you don’t set an expiry date, every single request for your page will lead to a request to the server to a. check if the image has changed, and b. download it if it hasn’t. That potentially means lots and lots of requests – like this:
Even though they aren’t downloading the images, all those requests take time. By adding a caching policy, we can make sure that those requests never happen. What we need is an HTTP header that tells the client to save the image until some specified date in the future:
With this header in place, a visit to the page (but not a browser refresh: that behaves differently) will lead to many fewer requests:
2. What do I do about it?
Different web servers will offer their own mechanisms for setting cache policies – but if you’re using Amazon S3, you have three options:
1. Setting the cache value programmatically:
The Amazon SDK provides the PutObjectRequest object. This has an AddHeader() method that accepts two arguments – the header key and value, both as strings. You could calculate the date as so many days/months/years in the future, but the upshot needs to be something along these lines.AddHeader(“expires”, “Mon, Jan 1 2024 11:11:11 GMT”);
2. Set cache policies directly on individual images:
You can do this via the AWS Management Console. Just select the individual image:
Then add the metadata rule you want and click Save:
3. Use a tool to set caching on an entire bucket:
There’s a free tool – cloudberry, which you can download here – which will do this for you. You need to give it your AWS keys, and then you can connect to your buckets. Right click on the bucket to bring up the Set HTTP Headers option:
Then tell it to add the header you want:
You’ll need to make sure your security policy is set to allow you to make the changes from your machine for this to work. I temporarily removed my policy and re-added it after the changes were complete – and now my images no longer require a 304 check every single time someone visits the page. Since S3 charges by usage, that could add up to significant savings over time as well as the obvious performance advantages.
For related information, check out these courses from Learning Tree: