Today we continue our blog series dedicated to the improvement of website performance using hints from The Ultimate WordPress Speed Optimization Guide written by Johnny Nguyen. This part is going to be about caching optimization:
Caching is best defined as saving the processed requests so they can be served faster when requested again. It’s used in every aspect of computer technology since forever, and absolutely essential for speeding up your page load.
There are many kinds of caching (across different layers, protocols, and services) and many ways to configure them. Set them up right and you’ll have a fast site that reduces server load and saves money. Set them up wrong and you have a site that’s sometimes-fast and or has broken design and functions.
If you’ve ever heard of people complaining about cache, it’s a combination of those who don’t know how to configure it for their use case and/or who use a caching solution configured for server-efficiency more than for speed.
Each caching optimization below hint will be marked with the level of required skills to implement and the impact it will bring.
- BEGINNER – can Google and follow instructions.
- INTERMEDIATE – working as WordPress contractor.
- ADVANCED – programmer or server-admin.
- LOW – maybe 100-200ms difference. Possibly unnoticeable.
- MEDIUM – around 500ms difference.
- HIGH – 1 second difference or more.
1. Choosing the Right Server for Caching (BEG-ADV, HIGH)
Full-page caching (aka “static caching” or just “caching”) means to prebuild the entire page, making it static like HTML so it’s ready to serve immediately when the page is visited. There is no wait for any database queries or PHP processing…the page simply appears instantly. Like a burger that was made before you order it!
Back in the days, caching was only done by the web server (therefore called “server caching”) and utilized to keep server load down. It was a tactic to help busy web servers handle lots of traffic. Somebody later realized it could help speed up today’s bloated sites so now, caching is also used from a speed point-of-view and deployed even on small webservers with little traffic.
Developers even created software-level caching mechanisms to recreate the same benefit for users without server access, or on servers without “server-caching” modules enabled. Of course, they’re not as fast as true server-caching but still massively impactful and in some cases even more useful because of having extra caching features.
The most important distinction for regular users is to know their caching limitations with each webhost or web-server. In terms of webserver, Apache, LiteSpeed, and NGINX all have different server-caching available.
In terms of webhosting, just know that some webhosts allow you the freedom to use their server-caching or any 3rd-party plugin of your choice. Other webhosts force you to use their proprietary caching solution. Of course, they will sell it as being high-tech and “best performance” but usually it’s a stripped-down caching solution that’s built for resource-efficiency rather than aggressive performance. If you try to use an outside plugin, it simply won’t work or the webhosting company will automatically disable it.
- Caching is usually faster and more resource-efficient from the server rather than through software-level PHP caching.
- If using LiteSpeed server, you can use built-in LiteSpeed server caching.
- If using NGINX server, you can use built-in FastCGI server caching.
- If using Apache (which you shouldn’t), you can use Varnish proxy or even NGINX proxy.
- All web-servers can use any software-level php caching (via cache plugin). But some plugins are designed more for Apache/LiteSpeed servers, others for NGINX servers.
- Careful of certain webhosts (especially “managed webhosts”) who force you to use their caching solutions and won’t let you use other cache plugins.
Just know that the webserver or webhosting company you choose will affect your caching experience and what caching plugins you can use.
2. Choosing the Right Cache Plugins (BEG-ADV, HIGH)
I’ve tried over 50 different cache plugins. The best ones have useful features, easy-to-use, and don’t break your site. If you manage only a few sites, you might prefer aggressive plugins with many optimizations and even Facebook groups where people share tricks. If you manage dozens of clients, you’ll prefer a safer plugin with less features and less chance of issues.
- Best all-around cache plugins (allowed on any webserver) are Swift Performance or WP Rocket. Swift more aggressive, Rocket more stable.
- There are other good cache plugins as well (WP Fastest Cache, Breeze, WP Performance, Comet Cache, Borlabs).
- W3TC sucks and very difficult to configure. Don’t use unless you’re a pro.
- If using LiteSpeed server, you can use LiteSpeed Cache plugin. My favorite.
- If using NGINX server, you can stick with NGINX helper plugins to keep it simple or a full-featured cache plugin like (Swift or WP Rocket).
- Do not combine multiple cache plugins!
- I don’t like combining cache plugins with other performance plugins either, but it can work if configured carefully (and not overlapping functions).
Deciding which cache plugin to use depends on your use case.
- Small site with 400 pages and little traffic? – Swift or WP Rocket, with precaching enabled.
- Medium site with 400-1k pages, and medium traffic? – Can go with cache plugin Swift/Rocket or server caching LiteSpeed/NGINX. Both have pros and cons.
- Big site with 1k or more pages and lots of traffic? – I like custom-configured LiteSpeed Cache or native-NGINX cache and no pre-caching necessary since you have so much traffic.
3. Cache Plugin Configuration (INT-ADV, HIGH)
Cache plugins are more complicated than ever to configure now since they do so many more things than just caching. This section covers specifically only caching-related settings. Regarding other options you see in cache plugin settings, my recommendation will be in other parts of this guide.
- Rewrites vs PHP – most cache plugins only give you the PHP option. If you have the option to use the rewrite method, try that as it’s faster. If it causes problems, then switch to php method.
- Cache TTL – this means how long the cache should last for. You should set this about as long as your content update intervals. If you update every day, then set 24 hours. If you almost never update, can make it 1 month.
- Private cache or logged-in users/pages – don’t use unless you really have that many logged-in users and you know how to prevent cache from mixing up content between users.
- Separate mobile cache – don’t use unless you have AMP or a specific design or content that only shows up on mobile. Just because you have a mobile-responsive site doesn’t mean you need this.
- Caching 404 pages – yes if you have many users hitting them. Better if you redirect all of them to actual pages.
- Dynamic cache – great for caching urls with queries or filters, like searches or ecommerce product filters.
- Exclude – absolutely critical for excluding pages that shouldn’t be cached. I typically exclude checkout, logged-in user pages, or pages with forms.
- Browser cache – yes, enable it.
- Heartbeat control – I usually disable for all pages except posts. Or if you need it on, you can increase its interval to every 120 seconds.
Not every caching setup or cache plugin will allow you to configure all those options. Don’t freak out if you don’t see them. In fact, there are so many possible settings…please refer to my cache configuration guides below:
- Swift Performance cache setup guide
- WP Rocket cache setup guide
- LiteSpeed cache setup guide
- For all other cache plugins, I think you can follow my guides above to get a general idea.
4. Configuring Cache-Prebuild (INT, MED-HIGH)
One of the most overlooked aspects of caching for me is the cache-prebuild process. Some plugins call it “cache-preload”, others call it “cache-warming” or “cache-crawler”. The cache-prebuild function is a mechanism that pre-caches pages so they load quickly when visited. Back in the old days, caching was only used on high traffic sites and so no cache-preload was necessary. The cache was built by the first visitor and all subsequent visitors benefitted from an already-built cache. This was fine since you had thousands of visits and only the very first person was unlucky to see a “slower” page.
But in today’s caching era, letting the “first person warm your cache” is a terrible idea if you have very little traffic. On a not-so-busy site with no cache prebuild, it might seem like all your visitors hit a cold (uncached) page. FYI: users hitting cold cache will see a slower page load than without any caching at all!
So anyway, we have cache-prebuilding now. There are very few servers that have or allow a server-wide cache prebuild function. They’re probably afraid of users abusing it. It’s in the same logic that many webhosts won’t allow you to use those broken-link checker plugins (because it eats up precious resources).
- LiteSpeed servers have a built-in cache crawl function. Few webhosts allow it on shared servers though. You’ll probably only get access if you have it on your own VPS.
- Anybody not on LiteSpeed….well, there are many server-level cache warming mechanism and scripts out there but not quite so user-friendly. You can search them out if you insist. It’s much easier if you’re on LiteSpeed, though.
- The only option (for most people) is to use a cache plugin that has cache prebuild functions built-in like Swift Performance and now WP Rocket (which copied that idea from Swift).
- Prebuilding improves the caching experience on your site by a whole lot. Enable it if you can!
There are a few instances where you SHOULD NOT use cache-prebuild. One is if you have many visitors, it’s useless since there’s already live traffic warming the cache. The other is when you have too many pages.
I would say 1k pages is the general threshold. If you have over 1k pages and you update your site often, I recommend NOT pre-caching since your server will use many resources and never even finish the job. If your cache gets purged before it ever finishes, it’s stuck in a perpetual cycle of constantly prebuilding cache that’s never used.
5. Object Caching Configuration (BEG-INT, MED-HIGH)
Object caching is useful for dynamic sites (constantly-refreshed data and/or can’t be cached) or any sites with lots of calculated numbers/reports in admin backend. Object caching saves the database calls in RAM so they don’t have to be looked up every time they’re queried.
Because RAM is precious (less abundant than hard drive space and necessary for running programs), object caching is not usually allowed on many shared hosting plans. Also it has to be enabled through the server…so it’s only possible if you have your own server or on a hosting plan that allows object caching.
- Object caching must be enabled from the server.
- Object caching can be managed through the webhosting control panel or WordPress plugin (Plugin is better).
- It’s best if you have a cache plugin that manages both page caching and object caching (like LiteSpeed Cache). This way, they purge cache at the same time.
- You can use an object cache expiry time of 5 to 10 minutes to be safe. But if your content isn’t update often, you can go higher like up to 30-60 minutes.
I recommend not to use object caching if you have just a static site. In some cases, it’s even slower than just plain page-caching. Enabling it “just in case” does not help! Of course, you can test and see for yourself.
Top reasons to use object cache:
- Slow admin backend.
- Slow database-heavy functions.
- Don’t know if your pages are suffering from slow query? Check with Query Monitor.
6. Browser Cache aka “htaccess expires headers” (BEG, LOW)
This is that common tactic where people paste a bunch of lines into their htaccess so static files are browser-cached for a long time (1 week, 1 month, or even a year) so users don’t have re-download them again. Maybe it was a big deal before…well it isn’t anymore.
- Many devices (like mobile) have limited space and delete their browser cache when they want, not when you want.
- Browser cache only helps for returning visitors, and many sites don’t have much repeat traffic anyway (Besides, it’s the new visitors that we care more about improving user experience.)
- If you want to use browser cache, it’s more conveniently done through a cache plugin…rather than copy-pasting long commands into your htaccess file.
7. Ignore Query Strings on Page Caching (BEG, MED)
Query strings are (the extra text at the end of urls) used to send information to the server. Examples of query strings below and what they do:
- search – show different search results. (e.g. search?=wordpress+tips)
- ref – lets the site track who referred the user and save info within conversion tracking software. (e.g. ref?=affiliateID)
- fbclid – lets the site know the user came from Facebook. (e.g. fbclid=123ABC)
- (product) filter – show different products based on name, price, size or other product specifications. (e.g. filter_size?=large)
As you can see, some of these query strings actually alter the page content whereas other strings show the same page content regardless of the query string. The idea here is to exclude the query strings (that don’t change content) from caching so your cache mechanism doesn’t store those hits as a different page. This would save your server from unnecessary work recaching the same page under a different url string AND serve the page faster to visitors from existing cache.
This makes a big difference for visitors coming in from query string urls such as Facebook ads, affiliate links, email newsletter links (with conversion-tracking).
- Here’s how you IGNORE Query Strings when Caching.
8. Private Caching for Logged-In Users (ADV, MED)
Private caching is rarely practiced as most sites don’t need it (they don’t have many logged-in users). Caching public pages is easy since everyone sees the same page. Caching private pages is hard because of having to cache how each user sees the page differently AND (preferably) not wasting so much space resaving mostly similar pages over and over in cache.
- Some private pages are easy – same content for all logged-in users, but something else for users not logged in.
- Some private pages are harder – shows mostly the same content but also custom data depending on the user (like their name/username).
- Other private pages are tricky – shows completely different content to each user.
The easiest way to deal with private pages is to use object caching instead of page caching. To be more aggressive, you can carefully enable private caching…BUT make sure users can’t see each other's info and the public can’t see private content.
There are certain mechanisms out there like LiteSpeed’s ESI feature where you can show different content and widgets depending on the users…which is nice. But ultimately at this level, you need to either hire a pro or spend lots of time to configure something that not only works but also doesn’t eat up so much resources (memory and space). Private caching is tough!
9. HTML-Caching at the Edge (INT, MED)
This is a relatively new technology for WordPress. There are several plugins and services out there that can cache your pages at the edge and use CDN mirrors to serve them to clients around the world. There are 3 main benefits:
- Caching done on their server, not yours – reduces your server load, helps slow webhosting, decrease server costs, allow caching even if server doesn’t have it. Basically…allows you fast speeds even if your webhosting/server sucks!
- HTML delivered from CDN – traditionally, CDN’s only transfer static assets like images and CSS/JS. With this new edge-caching for HTML, they can serve the HTML from the nearby pop server as well…theoretically improving page load for visitors far from your origin server.
- Further DDOS protection – since less of your server is used, less of your server is exposed to DDOS attacks.
Notable edge-caching plugins and services available:
- QUIC.cloud – from the makers of LiteSpeed webservers. Their Q.C service allows any website to benefit from LiteSpeed quickness even if they don’t have LiteSpeed servers.
- Shifter – sold as a “static site generator for WordPress”. Seems to be a very different user experience from the usual WordPress workflow.
- WP Cloudflare Super Page Cache – allows you to cache everything with the free Cloudflare plan. Something previous plugins have claimed to do but fail in one way or another.
- I believe there are some more but I can’t find them now.
Do you need these services, or are they beneficial if you already have a fast server? I think not so much. I don’t use any of them as I’m happy with my server caching already. But these can be great options for those on weaker servers. Keep an eye on this segment as I’m sure it will evolve quickly.
In the next part of this blog series we’ll cover security optimization for your websites, so stay tuned. For a full version of the article go to The Ultimate WordPress Speed Optimization Guide.
Need an optimized WordPress hosting that meets the needs of your project? Get in touch with Jelastic for choosing the best option and receiving technical assistance while migration.