How to set up, well, a CDN on WordPress

When we talk about a CDN, we talk about a network of delivery of content, mainly static. This means that we will serve content that does not change, such as images, videos and other elements of this style. When we talk about WordPress it would be, mainly, the Media section.

Surely when someone tells you to mount a CDN in your WordPress they tell you to mount everything with Cloudflare and forget, but, personally, I do not think it is always the best option for several reasons, the main one is a performance theme in “what is not static”.

To begin with, explain a little how a CDN system works. The idea is to put an intermediate layer between the user and the server. For example, this site is physically hosted in Barcelona (Spain). It is possible that someone from Argentina visits it, and if you want to read the information you have to make a request from Buenos Aires to Barcelona, probably passing through Miami, New York, London, Paris … and back. With a CDN that request would not have to make so many jumps because, for example, there might be a copy in Miami and that user receives the information from there. Great, right? Yes, but no. In the case of an electronic commerce or dynamic content the thing is complicated, since not everything can be cached, which means that among all these steps we also have to go through the CDN for content that can not really be cached. This can cause items to be cached that it does not touch unless we make the rules clear.

I’m going to put another case in small and based on some evidence I did a while ago. You have a site in Spain and that 95% of the traffic is from Spain. In Spain there are several operators, many global, others local. In any case you may be interested in having a CDN like Cloudflare that has two points, one in Madrid (Interxion) and one in Barcelona (Equinix). This makes it connected to Espanix and Catnix. With this we have connectivity with practically all the operators in the country. Taking this into account (and we are already talking about milliseconds) when we make a request to a static it is very likely that one of the two points of Cloudflare is the closest to serving the content, but in the case of a dynamically generated page your journey will be from the Device to Cloudflare, and Cloudflare will have to apply the rules, see that it does not comply with it, so Cloudflare will have to call your website, generate the response, return it, Cloudflare will process it and serve it to the user. Necessary? Not because 100% of dynamic content will have this problem. Yes, I know there are other pros and cons, but I want to focus on what is typical of a CDN.

With this in mind, how to make only static contents cached on a CDN with WordPress? To begin with, by default the Media that is uploaded to WordPress is hosted in the /wp-content/uploads/ folder, under the same domain. This means that it is not possible to search concretely only this part… but there is a trick, something that years ago WordPress showed by default and that is now hidden.

Configure DNS

The first step will be to create a subdomain (or another domain) that is going to be the one that we are going to cache and that will be the CDN really. To do this we will go to our list of DNS entries and create an entry of this style: A 123.456.789.123

It can be done with an A input, with a CNAME, with a DNAME… check with your hosting provider for the best way to do this.

The next thing to do is to configure where that subdomain points. The idea is that it does not point to the root folder of WordPress or a new folder, but to /wp-content/uploads/. As before, check with your provider to optimize this point.

The goal is that when you call you will actually call the one on the route. Both paths should work correctly because both hostnames point to the same sites.

Set up WordPress

The important thing about this system is that we try to touch WordPress as little as possible. If one day we want to undo this CDN system, it can be done easily by running a command. This means that physically, the files will continue to be uploaded and managed in the same place where WordPress usually saves them.

What we are going to do is a change in the WordPress configuration. These options came previously in the Settings section, but stopped appearing a while ago. Even if they are not visible, they are still in the WordPress core and their use is very useful.

To access the entire list of options we will visit from the Administration Panel an address such that This address is not accessible from the navigation menu, and basically displays a list of all the items in the options table.

Once there, we will examine the option upload_url_path which theoretically should be empty. What we will do is update it by saving the information with the button at the bottom of the page.

From this moment WordPress will manage the media with the new address.

Update previous routes

Before continuing, what we will do is update all the addresses of images or other content that we have throughout the site. For this case, I will use WP-CLI which is the fastest and easiest option, although you can use some other plugin to replace content.

We can first do a test in which we are informed of the changes that will be applied. To do this, we will execute the command:

wp search-replace '' '' --dry-run

If we see that the change is correct, we will execute the query completely and apply the changes in the database. Please make a copy of the database before doing this.

wp search-replace '' ''

With this change, if we go to the main page of our site or to the file of an entry or product we can see that the images do not call the URL with the WWW, but with the STATIC subdomain. This means that everything has worked properly.

Configure the CDN

To configure the CDN we have several previous jobs. The first thing is to look for the right CDN for us. The most advisable thing is that it also has a plugin for WordPress that is capable of managing the invalidation of other types of elements.

A good way to research is to do a search for CDN plugins for WordPress. There we will see systems and alternatives.

Configure the CDN

The first thing will be to create the account in the CDN and configure the DNS or whatever they ask us so that everything works correctly. It is very likely that this is a redoing the first step of the DNS, but you have to keep in mind that if one day you want to stop using the DNS service, you can always go back and leave it so that you have full control of the system yourself.

Install the CDN plugin

Once the account has been chosen and created within the CDN provider, we will install the plugin and configure it.

And theoretically, that’s it. From this moment, your website enjoys the Media part of a CDN system that will improve the times and optimizations of the part of the static contents that theoretically do not vary.

Extra: some CDNs

The question I am asked the most is which CDN to choose if we want to apply THIS SYSTEM. And I highlight the ESTE because as I explained at the beginning, there are systems that manage all your traffic because they require a control of the DNS (and therefore give away information about your site to providers who make money selling that information -anonymous or not-without you knowing it).

I’m going to start from the basis that your site moves 100GB of data per month. The figures I present are very approximate, but it is to give an idea.

Cloudflare200€/monthRequires Business account to maintain control of DNS
Amazon5€/monthThe free part is subtracted
Cloudinary0€/monthIn principle, consumption would enter into the free part
Stackpath0€/monthIn principle, consumption would enter into the free part

After all, having a CDN for an important project is important and very cheap.

About this document

This document is regulated by the EUPL v1.2 license, published in WP SysAdmin and created by Javier Casares. Please, if you use this content in your website, your presentation or any material you distribute, remember to mention this site or its author, and having to put the material you create under EUPL license.