CloudFront and W3 Total Cache

AWS CloudFront

After setting up WordPress in AWS and then switching off CloudFlare so I can use certificates from Amazon Certificate Manager, I noticed a pretty big drop in the GTMetrix score, specifically the YSlow report, and this was due to the lack of CDN (Content Delivery Network). Thankfully, I can progress with my studies of all things AWS, and set up CloudFront.

What is CloudFront?

CloudFront is a content delivery network, data can be pushed to it, or pulled by it to Amazons CloudFront edge locations, and delivered to the end-user. This should (hopefully) improve my YSlow score.

Setting up CloudFront

From the AWS console, find the CloudFront option, or search for it.

AWS CloudFront
Click on it and then select the Create Distribution button.

Create CloudFront distributionWe can use CloudFront for web traffic (HTML, CSS, and PHP for example), or for speeding up media streaming (RTMP). Select the Get Started button under “Web”:

CloudFront delivery methodIn the next page, we set our details, such as the Origin Domain Name. Actually, this is pretty much the ONLY thing you need to put in. But, seeing as we are here, let’s have a look at the options.

  • Origin Domain Name: As it suggests this is where CloudFront will get its content from.
  • Origin Path: This is used if your content is in an S3 bucket.
  • Origin ID: This is a description of the origin.
  • Origin SSL Protocols: What protocols our origin uses (if any, but it should) such as TLS1.2.
  • Origin Protocol Policy: What this does is if set to “Match Viewer” then if the client requests the site via HTTP, then CloudFront will pull the data using HTTP from the origin server, if the client is using HTTPS, then CloudFront will use HTTPS. Or we can force it to use HTTP or HTTPS. There are a few caveats about this setting:

    If your Amazon S3 bucket is configured as a website endpoint, you must specify HTTP Only. Amazon S3 doesn’t support HTTPS connections in that configuration.

    For HTTPS viewer requests that CloudFront forwards to this origin, one of the domain names in the SSL certificate on your origin server must match the domain name that you specify for Origin Domain Name. Otherwise, CloudFront responds to the viewer requests with an HTTP status code 502 (Bad Gateway) instead of the requested object.

    Both of these tips came from this guide to CloudFront.

Create CloudFront Distribution

Most of the other settings I left as the default, apart from when we get down to Distribution Settings. If we are going to use a custom DNS for this (which I am) then it needs to be added as an Alternate Domain Name (CNAMEs), there is also the option as to whether we want to use the default CloudFront certificate or our own IF it has been generated by ACM (Amazon Certificate Manager). I do have one from the previous post, so will use that instead. Clicking on the text field allows us to select a certificate from a drop-down menu:

CloudFront Distribution settings

You can also request a new certificate if there is not one already.

I left the rest of the settings as default. Finally, click “Create Distribution”.

As always, it takes a little time for it to be set up:

CloudFront distributions

Next it’s a good idea to create a CNAME in your DNS to point something more memorable to the CloudFront DNS. I set mine up as

Setting up W3 Total Cache for CloudFront

From the W3 Total Cache (W3TC) General settings, select the CDN option. Tick the box to enable CDN, and then select the CDN type. For CloudFront, we can have it pull or push. With Origin Pull, CloudFront will pull the files as they are needed. With Origin Push the files are pushed to CloudFront. I am using the Pull option.

**Edit 1: See my note at the end – it’s safer (less costly) to use the Generic Mirror option instead**

W3TC CloudFront CDNClick on Save all settings:

W3TC CloudFront settings Next, from the W3 menu, select CDN. You should see this error:

CloudFront access W3TCWe need to return to AWS to set up some credentials in Identity and Access Management (in AWS). You can find it under “Security, Identity, and Compliance”:

CloudFront IAM user
Clicking on this option opens up IAM, and click on Users to start creating our first user. Click on “Add user”. W3TC is asking for an access key and secret key. From the IAM page, we can see that this means we need to set the option for Programmatic access.

CloudFront IAM user detailsClick “Next: Permissions”.

On the next screen, select the option to “Create group”. I have seen a number of posts about this using full administrative access, but that seems like overkill and, quite frankly a little dangerous. Instead, do a search for CloudFront and add it to the CloudFrontFullAccess policy:

CloudFront IAM groupClick “Create group”.

Scroll down and click on the button that says Next: Review. Click on it, then select “Create user” on the next page.

Make a note of the URL that;’s shown and download the CSV file. Store it somewhere nice and safe.

For our immediate purposes, copy the Access key ID, and also get the Secret Access Key. Return to W3, and put the details in there.

Test the distribution, what we want to see is this, when we click on the test button:

CloudFront IAM W3TC
We also want to see this at the top:

CloudFront W3TC success

There is an easier way, which is to create the group and the user in IAM, then let W3TC do the heavy lifting by adding the access key ID and secret key, then clicking on “Create Distribution”. Although the way I have done it is longer, we get to see more of the AWS scenery!

If we look at the previous post, we can see that the links have already updated to reflect the new settings. When we hover over an image, it shows the aws-cdn URL instead:

CloudFront certificate
A promising start, however, actually opening the image in a new window opened it from a URL. Turn’s out that JetPack was doing a CDN for me…

CloudFront JetPackOnce this was turned of, the image opened from the correct URL, but the certificate was actually that of CloudFlare, not CloudFront. Agin, I needed to go back into the CloudFlare settings and switch the CNANE to DNS only (clicking on the orange cloud in the CloudFlare DNS console).

Once that was done, it was actually redirecting to the right place, but I had made a serious boo-boo with the certificate settings. The cert did not have an alternate name for, and the website looked shit.

I created a new certificate and set that in the CloudFront settings. Once it had updated and a browser refresh later, I got the intended result:

CloudFront certificate

The images are being served from the CloudFront distribution, with our SSL certificate.

What effect has this had on the YSlow report? Well, here is the first one taken (using CloudFlare):

GTMetrix CloudFlare

Here is the latest one:

GTMetrix CloudFront CDN

Not too far off, but the loading time has actually doubled. Where I am losing points is:

  • Leverage browser caching (setting expiration on objects such as javascript)
  • Add expires headers
  • Make fewer HTTP requests (too many external Javascript files and stylesheets)

W3TC is currently un-tuned. So, I did some tuning. which after a while seemed to sort things out. Things are looking (a little) better:

GTMetrix CloudFlare


There are still a few improvements to make, but I know it’ll never be a perfect score.

Interestingly, it seems that the more recent versions of W3TC can get you hit with a pretty hefty AWS bill for invalidations:

I switched mine to be a generic mirror to be on the safe side.

**Edit 2: being on the safe side seems to have stopped the CDN functionality… Back to the drawing board! **


I removed W3 Total Cache and installed WP Rocket instead. I use it over on and it worked well there. It is much easier to set up, and my score went up to this:

CloudFront WP RocketWell, some bits went up and some went down, but it’s using the CloudFront CDN now, which is what’s important!


Please enter your comment!
Please enter your name here

This site uses Akismet to reduce spam. Learn how your comment data is processed.