Leverage Browser Caching in WordPress with or without a plugin

One of the easiest ways to make your WordPress website faster – which involves no effort at all from your side, is to leverage browser caching in WordPress. This is one of the high priority tasks recommended by Google to make your website load faster. It is also recommended by sites such as GTMetrix or Google Pagespeed Insights to make your site faster.

What is Browser Caching?

Before we actually show you how to implement this, we are first going to discuss what is leverage browser caching in WordPress means and how it works?

Once we explain how it works, you can understand how it helps to make your pages load faster.

Essentially, when somebody visits a page, the browser needs to download all the resources server on that domain from the server. These include HTML, CSS file, JS, text, images, and any other assets) in order to load and display the current page. Now, rather than actually downloading everything over and over again each time you visit a different page on the same site, the browser uses what is called a Web Cache. This is a feature used by browsers to ‘temporarily store’ or ‘cache’ web page assets on the device’s local storage. This storage or data is called ‘ Web Cache’ or ‘HTTP Cache‘.

Have a look at this fun diagram which explains how the web cache works:

Leverage browser caching warning

Sites such as GTMetrix can show the following leverage browser caching warning, which you’ll need to fix if you haven’t activated the settings below.

Now, what does this actually mean?

Although the above-described function is great in theory, by default most websites will “mark” the content to expire after 8 days or a short period of time. What this means is that if a user visits your domain again after 1 week, they will need to download the resources all over again.

By leveraging browser caching, what we actually do is instruct the browser to extend the lifetime or expiry date of the resources which are downloaded by our visitors and consequently optimize performance.

Incidentally, if you are looking to make your WordPress fast, there are a few plugins such as this one which can make a real difference in performance in a few minutes (zero effort).

Not ready to use a plugin for now?

Change .htaccess to leverage browser caching in WordPress

To set the expiry time of resources such as images and CSS files, this requires a slight modification to your .htaccess file, which is found in the root of your hosting server. This is done by changing the expire headers to boost performance.

As a bare minimum, you add the following to your .htaccess. To do this, simply access your hosting C-Panel, and with your File Editor, find the .htaccess file and add the following to the bottom of the file. Do not make any other changes.

#Customize expires cache start - adjust the period according to your needs
<IfModule mod_expires.c>
  FileETag MTime Size
  AddOutputFilterByType DEFLATE text/plain text/html text/xml text/css application/xml application/xhtml+xml application/rss+xml application/javascript application/x-javascript
  ExpiresActive On
  ExpiresByType text/html "access 600 seconds"
  ExpiresByType application/xhtml+xml "access 600 seconds"
  ExpiresByType text/css "access 1 month"
  ExpiresByType text/javascript "access 1 month"
  ExpiresByType text/x-javascript "access 1 month"
  ExpiresByType application/javascript "access 1 month"
  ExpiresByType application/x-javascript "access 1 month"
  ExpiresByType application/x-shockwave-flash "access 1 month"
  ExpiresByType application/pdf "access 1 month"
  ExpiresByType image/x-icon "access 1 year"
  ExpiresByType image/jpg "access 1 year"  
  ExpiresByType image/jpeg "access 1 year"
  ExpiresByType image/png "access 1 year"
  ExpiresByType image/gif "access 1 year"
  ExpiresDefault "access 1 month"
</IfModule> #Expires cache end

We are setting assets which refresh quickly such as the HTML of your page to expire after 600 seconds, whilst we are changing such things as the CSS and Javascript to only expire one a month.

This means, that if your visitor visits the page again within a month, they don’t need to redownload your CSS and JS assets again. If you know that you rarely perform these types of changes on your site – you can set the value higher, to 1 year, similar to the jpeg, png expires header.

This is the most effective way to leverage browser caching for WordPress or other websites which make use of a .htaccess file.

Add Cache-Control Headers

The following setting should also be added to the file to set the cache-control headers as discussed above.

# BEGIN Cache-Control Headers
<IfModule mod_expires.c> <IfModule mod_headers.c> <filesMatch "\.(ico|jpe?g|png|gif|swf)$"> Header append Cache-Control "public" </filesMatch> <filesMatch "\.(css)$"> Header append Cache-Control "public" </filesMatch> <filesMatch "\.(js)$"> Header append Cache-Control "private" </filesMatch> <filesMatch "\.(x?html?|php)$"> Header append Cache-Control "private, must-revalidate" </filesMatch> </IfModule> </IfModule>

(Multi-server sites or CDNs) Unset ETag headers

The final thing which we need to do is (un)set the Etags setting.

Essentially, this is important only if you are using a CDN to serve some of your resources. Etags are headers that are typically constructed using attributes that make them unique to each specific machine hosting a site (technical reason – it uses an MD5 generated by the server, making it unique to the server generating it).

If a website is using a CDN or multiple servers to serve their pages, there is NO guarantee that the same server will be used – therefore the tags will not match when a browser gets the original component from one server and later tries to validate that component on a different server.

For this reason, it would be best to UNSET them if you are using multiple servers or a CDN to host your website. This allows the Cache-control headers to actually control the caching rather than the ETags. Given that we’ve put in settings to control the cache through the Cache-Control headers, the ETags are no longer necessary – so we’ll switch them off. Add this to your .htaccess to unset them.

# Disable ETags
<IfModule mod_headers.c>
	Header unset ETag
FileETag None

If you need to read more about what the Etags do, you can find more details and read about them in this article: https://en.wikipedia.org/wiki/HTTP_ETag

Recommended Caching Plugins

Leverage Browser Caching for Nginx

If your website is actually using Nginx as its server, you will need a different code, because Nginx does not have an .htaccess file. However, it’s still relatively easy to implement this, because you just need to perform a few edits in the conf file of the server.

You need to add the code below inside of an existing server block in your conf file. This will typically be in /etc/nginx/sites-enabled/default

server {
    listen       80;
    server_name  localhost;

    location / {
        root   /usr/share/nginx/html;
        index  index.html index.htm;

    location ~*  \.(jpg|jpeg|png|gif|ico|css|js)$ {
        expires 365d;

    location ~*  \.(pdf)$ {
        expires 30d;

Add Cache-Control Headers for Nginx

location ~* \.(jpg|jpeg|png|gif|ico|css|js)$ {
expires 90d;
add_header Cache-Control "public, no-transform";

As you can deduce from the code above, we’re setting the expiry location for image files to 1 year or 365 days, whilst we’re setting PDFs to expire after 30 days. You can add more file extensions to customize the expiration making it different for other filetypes.