How to Apply Expires Header to WordPress to Optimize Cache-Control

by | Last Updated on December 23rd, 2018

Level of Difficulty – [Easy]

IMPORTANT! Editing the Source Code of a WordPress theme could break your site if it’s not done correctly. If you are NOT comfortable doing this, please check with a developer before continuing. SpeedRak Will Not Be Responsible for a Broken Site!

A fast response time is not your only concern when designing your web site.

If it were, then you would take rule #1, reduce HTTP requests for increased site speed, to the extreme and not place any images, scripts or CSS stylesheets in your pages.

How to Apply Expires Header to WordPress to Optimize Cache-Control

Add Expires Header & Optimize Cache-Control

As you probably know, Google is Obsessed with your website’s speed, and considering that today’s dynamic, database-driven web sites have a reputation for slow loading times, we need to pull out ALL the stops and use each and every tool offered, at your disposal.

Another excellent way to begin improving your website’s performance is by setting a “Far-Future Expiration-Date” for various files within your site.

Optimizing Cache-Control to Boost Your Site Speed

The best solution to improve your caching across all browser platforms is to use an Expires Header set with ‘ExpiresDefault’ directive, as shown in the scripting below ‘# Default Directive

Adding Expires Header & Optimizing Cache-Control, will specify an expiration date for all forms of images, JavaScripts and CSS stylesheets, so that your browser can cache these files to be used for subsequent web page visits.

Browsers use this cache to reduce the number of HTTP Requests making web pages load faster. A web server uses the Expires Header to tell the web client that it can use the current copy of a component, that is stored in your browser’s cache, until a specified time.

Techno Geek – On subsequent requests the browser will check the cache to find if the components have expired. If the components haven’t changed, the origin server will avoid sending the entire components and instead send back a few headers telling the browser to use the components in its browser cache.

– – – –

FOR EXAMPLE: The first time a browser loads a web page, it will load the files required for the look, feel and functionality of the page (I.E. – images, stylesheets and scripts), into its cache.

For subsequent or future page visits, the browser will check the Expires Header for each file, and will load anything that hasn’t expired, directly from its cache, speeding up a web page’s response time.

– – – –

Expires Header – Optimizing Cache-Control with Mod_Expires

The conventional method of customizing cache-control utilizes Apache’s (Server language) expires-module, mod_expires.

Once mod_expires is enabled in the main configuration file (httpd.conf on your server), mod_expires can be configured using 3 mod_expires directives: ExpiresActive, ExpiresByType, and ExpiresDefault.

These methods are best located within the httpd.conf file in your server, but also work great when included in the sites root .htaccess file.

Knowing that Google is Obsessed with site speed, and this simple piece of scripting is one solution of many towards improving your site’s performance, we have provided an easy way for you to copy and paste the code into your site’s .htaccess file for increased website’s speed.

Implementing Cache-Control Using Mod_Expires Directives

In order to improve your site’s speed and performance, we will be setting the Expires Headers for various types of files.

The next step will require you to have access to the directory files of your website or blog to locate the ‘.htaccess’ file.

This .htaccess file may be located in the root directory or any sub-directory of your site and, it is not always visible by default.

If your site is controlled using cPanel… go to your ‘File Manager’, then checkmark the “Show Hidden Files”. When you open the ‘File Manager’, look for .htaccess… click on it, then click on ‘Edit’, then add the scripting below.

cPanel File Manager

The wording with the ‘#’ are for descriptive purposes and are not required…

You can place this scripting after other code that is within your .htaccess file.

# Optimize cache-control
<IfModule mod_expires.c>
ExpiresActive on
ExpiresDefault “access plus 1 month”
ExpiresByType image/gif “access plus 1 month”
ExpiresByType image/png “access plus 1 month”
ExpiresByType image/jpg “access plus 1 month”
ExpiresByType image/jpeg “access plus 1 month”
ExpiresByType text/html “access plus 3 days”
ExpiresByType text/xml “access plus 1 seconds”
ExpiresByType text/plain “access plus 1 seconds”
ExpiresByType application/xml “access plus 1 seconds”
ExpiresByType application/rss+xml “access plus 1 seconds”
ExpiresByType application/json “access plus 1 seconds”
ExpiresByType text/css “access plus 1 week”
ExpiresByType text/javascript “access plus 1 week”
ExpiresByType application/javascript “access plus 1 week”
ExpiresByType application/x-javascript “access plus 1 week”
ExpiresByType image/x-ico “access plus 1 year”
ExpiresByType image/x-icon “access plus 1 year”
ExpiresByType application/pdf “access plus 1 month”
<IfModule mod_headers.c>
Header unset ETag
Header unset Pragma
Header unset Last-Modified
Header append Cache-Control “public, no-transform, must-revalidate”
Header set Last-modified “Mon, 1 Oct 2018 10:10:10 GMT”

Once in place, these directives will set Expires Headers for the specified file types. There are six main things happening with this technique:

  • Enable the module using the ExpiresActive directive
  • Set the default cache-duration using the ExpiresDefault directive
  • Define the cache-duration for specific file-types using the ExpiresByType
  • Remove the Last-Modified, Pragma, and ETag Headers
  • Optimize the response with Cache-Control Headers for HTTPS (“public”) and proxies (“no-transform”), and also to force revalidation of stale content (“must-revalidate”).
  • Reset the Last-Modified date

You can also fine-tune the ‘ExpiresByType’ directive as needed for your specific file.

Although the scripting looks complex, optimizing the cache-control to your liking is relatively easy and straight forward.

If you would like to change any of the cache-control Expires date, just change the ‘access plus 1 month’ or ‘access plus 1 year’, etc, to ‘access plus 1 week’, ‘access plus 1 day’, ‘access plus 2 months’, etc… you get the idea.

You can set longer cache-durations for images, videos, and other media files. Normally, these files don’t change once they’ve been uploaded to the server.

The same for other types of files such as fonts, favicons, PDF’s, and so on — they’re generally updated much less frequently, and so may be safely cached for longer periods of time.

You could easily go a month or more… this is the whole point of fine-tuning your cache-control expires directives, to correlate as closely as possible with what’s actually happening with your website.

Additional File-Types for Mod_Expires:

You can add any of the file-types below within your script (above)… just be sure to place them sequential with the other ‘ExpiresByType’ scripts.

ExpiresByType image/jpe “access plus 1 month”
ExpiresByType video/ogg “access plus 1 month”
ExpiresByType audio/ogg “access plus 1 month”
ExpiresByType video/mp4 “access plus 1 month”
ExpiresByType video/webm “access plus 1 month”
ExpiresByType application/x-font-ttf “access plus 1 month”
ExpiresByType font/opentype “access plus 1 month”
ExpiresByType application/font-woff “access plus 1 month”
ExpiresByType image/svg+xml “access plus 1 month”
ExpiresByType application/ “access plus 1 month”

Closing Comments – Optimizing Cache-Control with Expires Header

It’s amazing that something so simple, added to your WordPress site, can double, if not triple, the speed of the subsequent page views.

TRY THIS TEST… click on the ‘Home‘ link above…

After you have landed on the page, click on the ‘Home‘ link again to see the incredible speed difference for the second click.

Try any other link, then click on the same link a second time… doing this will give you an idea to what this scripting can do for your site.

– – –

Making a move to improve your site’s performance is the first step that will assist in making your visitors happy, AND, it will make Google begin raising its algorithmic eyebrows, in a good way, because you are trying everything in your power to improve your Site’s Speed and Performance.

NOTE: This method of setting Expires Headers with the ExpiresDefault directive is usually the best way to go about optimizing your cache-control, but there is another method that is worth mentioning, at a later time, because of its added flexibility.

Until then… grab every tip and every method a person is willing to share with you and put it to work to improve your site’s performance and increase its speed.

Much of the Expires Header & Cache-Control mentioned above are take-away’s from the book “.HTAccess Made Easy” ~ Written by Jeff Starr

NOW It’s YOUR Turn… Have You Run Your Site Through GTMetrix to See How Your Site Performs? Be Sure to Share YOUR Comments and Discoveries Below!

If You Liked It - Please Share It!


Comments (6)

  1. I tried all the tags in my website but in Gtmatrix show no Add Expires headers Grade -F (0).
    Now what can I do?

    • John Engle says:

      Hey Sumant,

      I ran your site through GTMetrix… everything that shows a BAD Grade, you have NO control over. Everything is an external site/link that is not any part of your site. Example… you have a large amount of Youtube and Google Ad links. You have ZERO control over those sites for their lack of Expires Headers, or any other issues that GTMetrix shows. You have control over your site ONLY.

      If you are interested in improving your site’s loading time, the only thing that GTMetrix shows that your site is lacking is a Content Delivery Network. The other would be to look at the GTMetrix information and get rid of some of those links that you find are causing the major issues.

      You also have a broken image link:

      Let me know how else I can help…


  2. Miriam says:

    Thank you so much! I just did this after getting so stressed out and overwhelmed by all this and it worked! You made it easy to understand and read and accomplish so THANK YOU!

  3. Forextr says:

    Good day John and readers

    According to GTMetrix our PageSpeed is now 93% and YSlow 75%. Google reported 64% and 84% for Mobile and Desktop respectively.

    First we checked “Optimize Website” (via Cpanel) and then we applied your Optimize Cache-Control script. [We specifically didn’t want to use another plugin – feels as if we are already using too many.] What a difference it made … thank you for providing this information!


    1. Google still reported 7 cacheable resources and GTM 11 items. Should we be concerned about them or not? How do we include them in your cache control? Strangely enough, there are 2 x .gif amongst them. The rest are 8 x js and 1 x css.

    2. The second issue we need to address is eliminate or defer rendering blocking JS. Both Google and GTM took issue with this. Have you done a post on it?

    3. And finally, GTM in particular was not happy with the number of HTTP requests. Can you point us in a direction to fix this please?

    And that’s it. Once again thank you. Eddie

    • John E. says:

      Sorry for the late response Eddie…

      What you are probably seeing on GTMetrix are cache-able resources, JavaScripts, and CSS that you have no control over. Meaning, look at the website address for these files… if they are from Google, Twitter, Facebook or another website, etc., you have no control over them, but GTMetrix will still read them and tell you about them.

      Render blocking JavaScript usually means that these files are in the Head section of your website… if you are not familiar with what a Render Blocking file is… here is a quick explanation: “Simply put, render blocking is a way of saying that the file or script will not allow any additional information to download to the users browser until the render blocking file is completely loaded. This means that if there is a delay for the retrieval of the file, the remainder of the site will have to wait until it is complete.”

      As for “eliminating” or “defer” the files… if these files are not part of your website, you have no control over them… here is a good explanation for what “defer”:

      And… here is what a JavaScript file that is deferred looks like:
      <script src="//" async defer></script>… I BOLD the word “defer“… believe it or not, if you have access to the JavaSript file in question, you can put the word defer into the script string. NOTE: Not all JavaScript’s can use the “defer” and have your site still function properly… keep that in mind.

      If you want to reduce your HTTP requests… read this article and apply what you can: How to Reduce Your HTTP Requests – Increase Your Site Speed

      I hope this information helps you Eddie… let me know your thoughts!


Leave a Reply

Your email address will not be published. Required fields are marked *