How to Add Expires Headers to WordPress (Detailed Guide)

How to Add Expires Headers To Your WordPress Website

Have you ever come across a recommendation that reads, “add expires headers”? If you have, then you aren’t alone. It’s one of the most common website performance-related recommendations that you’ll get when you start optimizing your site.

In this article, we will be going through a detailed tutorial on how to add expires headers to your WordPress website.

So, let’s get started.

What are Expires Headers?

Expires headers tell the browsers what resource can be stored and fetched from the browser’s cache or the source itself. In effect, it’ll

Help your site load faster by being able to display certain elements from the cache and not having to get it from the page speed

To make it work, the expires headers need to be set by the website owner. By doing so, the browser stores the resources locally for a given period of time set through expires headers.

For example, if you set expires headers on JPEG files, the browser will store all the JPEG files in its cache. This means a visitor can load the site faster as the browser has cached some resources related to the site.

By using expires headers, you will improve your site’s speed by reducing HTTP requests (the method used to communicate between browser and a server) between your computer and the server.

Learning About Browser Caching

Browser caching enables the browser to cache to locally store resources improving site speed.

So, how does it work?

The browser sends a request to a server when you load a website. The server, in return, sends the necessary resources.

In the pursuit to load sites faster, browsers can use expires headers to identify which resources can be loaded locally from the browser cache.

Not sure, what we mean? Let’s see browser-caching in action.

GTMetrix is a website speed and performance optimization site. It shows you a detailed report of how your site loads.

As you can see, WPAstra’s main site utilizes browser caching. All of these are possible because of expires headers.

Browsing caching with the help of expires headers can lower website load time by reducing HTTP requests between your computer and the server.

Sujay Pawar

Hello! My name is Sujay and I’m CEO of Astra.

We’re on a mission to help small businesses grow online with affordable software products and the education you need to succeed.

Leave a comment below if you want to join the conversation, or click here if you would like personal help or to engage with our team privately.

How Expiration Headers Work With Browser Caching

The browser cache stores resources based on the rules in the expiration headers (another name for expires headers). These rules enforce how the resources are used when a browser loads a site.

So, basically if a resource’s age isn’t expired, it’s loaded from browser cache. If not, then your computer requests it from the server again.

But, what happens when a site is requested by a computer for the first time?

In that case, all the site’s resources are directly downloaded from the server.

From the second time onwards, the browser will check its cache for non-expired resources and utilize it to save bandwidth and time.

If you want to learn more about it technically, we have covered it below. However, if you’ren’t interested, you can jump to the next section!

Illustration displaying the methods and ways of how browser caching works.

As you can see from the image, the browser first checks with the resource cache (browser cache).

The information is then sent from the server to the browser via HTTP headers. All you need to know about HTTP headers is that they are used to send additional information between your computer and the server.

Another important concept that makes all of these happen is: Cache-Control.

With Cache-Control, you can define browser-caching policies that work on both server and client-side.

If you check the images above, you will see that the expiration time set in the HTTP header is done using Cache-Control.

In short, Cache-Control offers a better way to implement browser cache as it overcomes the browser-based cache.

For instance, it looks after the following.

  • Resources that need to be cached
  • Where to store the cache
  • Maximum age after which the cache expires

Let’s see cache-control in action on

Cache-Control setting for CSS file

If you’re curious to learn more, we recommend checking out the Cache-Control – HTTP guide on Mozilla MDN or read Google’s guide on it.

If you also want to learn more about caching and how it’s related to WordPress, check out our ultimate guide to WordPress caching post.

Why Expiration Headers are Important

Expiration headers are important for the following reasons

  • It helps your site to load faster (after the first initial request)
  • It helps your server to manage more requests at any given time.

Which Resources You Should Cache Using Expires Headers?

Expires headers are useful if you know which resources you need to cache. For any general blogging site, implementing expires headers is easy as the rules can be applied to a wide range of resources, including images, videos, and so on.

But, the challenge comes when you need to implement a complex site such as eCommerce.

In both cases, the goal is to reduce HTTP requests and not increase them.

So, which resources, do you need to cache? Let’s go through a couple of scenarios to get a better understanding.

Scenario 1: Setting resource expiration age too long

If you set the resource expiration age for a long time, then the resource will be served to the user without any change for that given time.

In this case, if you decide to make changes to the site within that given period, the user will still see older versions of the site until the resource expires.

This can be solved by defining expiration time based on the resource type. In general, try to avoid adding default time span to all the resources.

For instance, you shouldn’t cache an entire section of scripts, HTML, images or other forms of the resources.

Even if you decide to do so, you need to make sure you know the impact of the changes on your site.

Asking yourself questions such as, “Will all the pages on my site function properly if I cache X or Y resource?”, can help you to implement expires headers correctly.

Generally, it’s a good idea to add expires headers to static resources as they are changed the least.

Scenario 2: Running a functionally complex site such as an eCommerce site

If you’re running an eCommerce site, you should be wary of the issues that come with expiration headers.

Let’s go through an example below.

A user visits your eCommerce site and adds new items to the shopping cart. However, if the resources on your site are cached incorrectly, then previously added products by the user(from a previous session) will show up in the shopping cart instead of freshly added products.

The buyer can solve the problem by pressing CTRL + F5 (forces a cache refresh), but that would be too much to ask from the buyer. Also, it creates a bad user experience and will surely impact user retention and sales figures.

So, where does this leave us? As an eCommerce owner, you can decide to add expires headers to resources based on their impact on user experience. Your goal is to provide a seamless user experience without breaking the site.

If all of these seems a little too complicated and overwhelming, don’t worry, all you need to know is that expires headers tells your browser what to get from cache, and what not to.

Your job is deciding what to and not to set. And we’ve got you covered on that, just read on.

Does Expires Headers Solve Slow Website Loading Time?

Not all sites are created equally and that changes how expires headers work.

For example, if you cache an eCommerce site improperly, you’re bound to get errors that directly affect the functionality of the site. It will also slow down the site.

For other generic sites, expires headers will improve website loading time by reducing HTTP requests.

In some cases, expires headers can slow down the site if not implemented correctly.

How to Add Expires Headers to Your WordPress Website

Excellent, if you made it this far, you deserve a cookie!

WordPress is a versatile content management system. This means it’s flexible and offers multiple ways to cope with a problem.

That’s why, in this section, we’re going to show you how to add expires headers manually to servers such as Apache Server, Nginx, and CDN Systems.

We will also show you how to add expires headers using plugins. (Yup, we know, this is mainly what you came to read.)

Adding Expires Headers Manually

Apache Server

One of the easiest ways to add expires headers to a WordPress site running on Apache server is to do it through the .htaccess file.

You can access it through two methods.

  • cPanel
  • FTP Client such as FileZilla

For the sake of simplicity, we’re going to use the first method. The method also applies to FTP clients if you know how to connect to your web server using it.

First, you need to login to your cPanel. If you’re using any popular hosting platform such as Bluehost or In Motion Hosting, you should have an option as shown below.

Arrow showing the button to log in to hosting's cPanel

Click on it, and you should be able to access the cPanel.

There, you will find the File Manager option.

Arrow showing the File Manager on the hosting's cPanel

From there, click on the File Manager and then proceed to click on the “public_html” folder.

Host's root directory shown in the File Manager

Once you’re inside the folder, you need to search for .htaccess file. If you aren’t able to find it, then make sure that the hidden files are set to “show.”

Arrow showing the htaccess file on the File Manager

Now, open the file by right-clicking it and “edit.”

Arrow showing the context menu of the htaccess with edit option

Now, you need to add the following code to the file and save it.

<IfModule mod_expires.c>
  ExpiresActive On
  # Images
  ExpiresByType image/jpeg "access plus 1 year"
  ExpiresByType image/gif "access plus 1 year"
  ExpiresByType image/png "access plus 1 year"
  ExpiresByType image/webp "access plus 1 year"
  ExpiresByType image/svg+xml "access plus 1 year"
  ExpiresByType image/x-icon "access plus 1 year"
  # Video
  ExpiresByType video/mp4 "access plus 1 year"
  ExpiresByType video/mpeg "access plus 1 year"
  # CSS, JavaScript
  ExpiresByType text/css "access plus 1 month"
  ExpiresByType text/javascript "access plus 1 month"
  ExpiresByType application/javascript "access plus 1 month"
  # Others
  ExpiresByType application/pdf "access plus 1 month"
  ExpiresByType application/x-shockwave-flash "access plus 1 month"

As you can see, we have added expires headers for different types of resources, including images, video, CSS, JavaSCript, and others.

Does the code look complex? Don’t worry as all you need to do is copy-paste the code in the .htaccess file.

But, if you’re confident and know what the code does, then you can alter the code according to your requirements.

For an eCommerce site, you simply cannot put all the static files in one single folder and then apply the same expires headers rules.

The best approach is to create multiple folders and use .htaccess files in each of those folders to gain finer control.

Another way, you can improve browser-caching is to add Cache-Control.

To add Cache-Control, you need to add the following code in .htaccess file.

# 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 "\.(css)$">
      Header append Cache-Control "public"
    <filesMatch "\.(js)$">
      Header append Cache-Control "private"
    <filesMatch "\.(x?html?|php)$">
      Header append Cache-Control "private, must-revalidate"


NGINX works differently than the Apache server. That’s why you won’t be able to find the .htaccess file.

The reason behind it’s due to the core NGINX philosophy for performance. By eliminating the need for the .htaccess file, the server can access information faster.

If you want to read more about it, then check out this article here: Like Apache: .htaccess.

So, how do you add expires headers to NGINX?

To do so, you need to edit the main server block. Once you made the necessary edits, you need to reload NGINX for them to take effect.

Just copy the code as shown below and add it to the server block. This will set the expires headers in NGINX.

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

location ~* \.(pdf|css|html|js|swf)$ {
   expires 2d;

Alternatively, you can also use the Cache-Control header. To do so, add the following line to the server block.

Restart the server for the Cache-Control header to take effect.

CDN Systems

If you’re using CDN for delivering content, then you have to use a different expiration date for your resources. To bypass this, you can unset ETags from the CDN server. All you need to do is add the following in .htaccess file.

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

Adding Expires Headers Using Plugin

Manually adding expires headers requires some technical expertise. However, if you’ren’t well-equipped with the technological know-how or in a hurry to enable browser caching, then you can use plugins.

In this section, we will show steps on how to add expires headers using two popular plugins, Hummingbird and WP Rocket.

1. Hummingbird

Hummingbird is a free-to-use plugin that lets you optimize your site’s speed. It also comes with good caching options.

The first step is to go to your WordPress site’s dashboard. From there, go to “Plugins” >> “Add New.”

From there, you need to type “Hummingbird” in the search option at the top right. Once done, you will find the plugin. Click on “Install Now” to install it.

Installing and activating the Hummingbird plugin

After activating the plugin, you will now see its list on the WordPress dashboard menu. Click on it and then select “Dashboard,” and finally, “Caching.”

Once you’re there, you will see 4 options. Click on browser caching to proceed further.

Browser caching option in the Hummingbird Plugin

At the top, it will show you the status.

Hummingbird plugin browser caching status

And, if you scroll down, you will see the option to configure browser cache using Hummingbird.

Option to configure browsing cache using the Hummingbird Plugin

Here, you will find multiple options to configure. You can choose the server type including Apache, NGINX, IIS, and Cloudflare.

Next, you can set an expiry time for all file types and do it on individual types.

Setting the expiry time on the Hummingbird Plugin

Lastly, you can also manually add expires headers using the manual option. The manual option generates the code based on your preferences.

If everything is set, you can click on “Activate” to enable browser caching using expires headers.

2. WP Rocket

WP Rocket (WP Rocket review) is also a good choice when it comes to adding expires headers to your WordPress site.

All you need to do is buy the plugin and install it. Activating the plugin will automatically modify the .htaccess file with the required rules.

FAQs About Adding Expires Headers

What should be the expiration time?

You can set the expiration time for any resources in years, months, weeks, and so on. However, this doesn’t mean that you should set an unrealistic expiration date.

The best approach is to make an educated guess on how long the resource needs time before it’s refreshed. Most of the time, static files are good candidates for a long expiration time. However, it’s better to add low expiration time for files such as HTML, CSS, and JavaScript.

How can I test if my changes worked after adding expires headers?

The best way to test if your expires headers are working or not is to use tools such as GTMetrix, Google PageSpeed, and Pingdom.


It’s clear that expires headers improve website loading speed. Even though it’s not going to make considerable changes to your site’s speed — the technique is bound to enhance the user’s experience.

With that said, it’s essential to know how to implement expires headers correctly. If you do it wrong, it will slow your site down. This is especially true for more dynamic and functional sites such as eCommerce sites.

Moreover, most of the sites will do fine with the code-snippet that we shared in the article for expires headers.

If you’re still not sure what to do, then we suggest you use the comment section below and let us know! We’re here to help!

Join 635,020 Subscribers

Get exclusive access to new tips, articles, guides, updates, and more.


  1. Mark Profile Pic

    Okay, but who knew Expires Headers was such a thing.

    I kept getting these errors and didn’t know what in the world they were. Awesome job in explaining. Helped a ton!

    1. Support Team Profile Pic

      Exactly! We found very few articles speaking about it and therefore thought of introducing it here in detail.

      Glad that it helped. 🙂

  2. Fadi Profile Pic


    thanks for the article its very useful. but please I just need to clarify to do it manual .htaccess.

    am using the Woocommerce plugin. I noticed you said if u are using e-commerce better to add Cache-control to .htaccess.
    you mean to add both expires headers rules and Cache-Control.
    or only cache-control. ??

    Thanks, And Regards.

    1. Support Team Profile Pic

      Hello Fadi,

      Well, both have different use as we mentioned – Expires headers are useful if you know which resources you need to cache.

      While Browser caching or Cache-control would help store the files locally to improve the speed.

      You can choose among them which suits best for your requirement.

      I hope that helps.

  3. Queen Andrade Profile Pic

    I kept getting these messages whenever I run a GT Metrix test and had absolutely no clue what it was.

    Glad to have found your article. Very helpful thank you!

  4. Ahmad Berry Profile Pic

    Okay but which plugin is the best?

    Also, if I can recall this is included in most every caching plugin out there. Right?

    Great job on the explanation, nevertheless!

  5. Garfield Brown Profile Pic

    Expires headers. Feels kinda weird saying it out loud, but who knew there was so much more to it.

    Excellent post by the way!

  6. Karan Badlani Profile Pic


    Thanks a lot for this post.

    I suggest everyone to take a backup of your htaccess file before editing it. It’s important 🙂

  7. Jean Profile Pic

    I followed every instruction and entered the codes. Despite reducing the page speed, it increased my site speed from 3.1 to 7.5 seconds.

    1. Support Team Profile Pic

      Hello Jean,

      That’s strange! Can you confirm the codes if added manually and if done using the plugin do check or confirm once with the relevant plugin author?

      I hope that helps.

  8. Jose Profile Pic

    Okay, but who knew Expires Headers was such a thing.

    I kept getting these errors and didn’t know what in the world they were. Awesome job in explaining. Helped a ton!

  9. Monica Profile Pic

    “How Expiration Headers Work With Browser Caching” Just the question I needed answered.

    Thanks for all the info. Really good stuff right here.

  10. Micaela Harris Profile Pic

    I kept getting these messages whenever I run a GT Metrix test and had absolutely no clue what it was.

    Glad to have found your article. Very helpful thank you!

  11. Henley Profile Pic

    Okay, but who knew Expires Headers was such a thing.

    I kept getting these errors and didn’t know what in the world they were. Awesome job in explaining. Helped a ton!

Leave a Comment

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

Scroll to Top
Now choose your preferred
page builder addon
Choose your preferred page builder addon

Download is Just A Click Away!

Enter your email address and be the first to learn about updates and new features.

Download Free Astra Theme - Modal Popup Form