How to Add Expires Headers to Google Analytics

Cody Schneider8 min read

If you've ever run your website through a speed testing tool like GTmetrix or Google PageSpeed Insights, you've probably seen a warning to "leverage browser caching" for the Google Analytics script. It feels strange - Google’s own tool is telling you that Google's other tool is slowing down your site. This article will show you exactly how to fix that warning by hosting the Google Analytics script yourself and adding the necessary expires headers.

GraphedGraphed

Build AI Agents for Marketing

Build virtual employees that run your go to market. Connect your data sources, deploy autonomous agents, and grow your company.

Watch Graphed demo video

What Are Expires Headers and Browser Caching?

Before we jump into the "how," let's quickly cover the "what." When a visitor lands on your website, their browser has to download all the files that make up the page - HTML, CSS, images, and scripts (like the Google Analytics script).

Browser caching is a simple but brilliant idea: instead of re-downloading these files every single time a user visits a new page or returns to your site, the browser stores a local copy. The next time the file is needed, the browser just grabs it from its local storage, which is much, much faster than fetching it from your server again.

Expires headers are the instructions you give to the browser, telling it how long it should hold onto these locally stored files before checking for a new version. By setting a long expiration date (e.g., one year), you’re telling the browser it’s safe to use the local copy for a long time, which leads to faster load times for repeat visitors.

So, Why Does Google Analytics Trigger a Caching Warning?

This is the core of the problem. Your website's Google Analytics tracking code calls an external JavaScript file (usually analytics.js or gtag.js) that is hosted on Google’s servers, not yours. You have no control over Google's servers, so you can't add your own expires headers to that file.

Google intentionally sets a very short cache expiration time on this script - often just two hours. They do this so they can roll out updates and new features quickly, ensuring a user's browser fetches a fresh version frequently. While this makes sense for Google, it hurts your site speed scores because tools correctly identify it as a file with a short cache lifetime.

Since we can't change Google's server settings, the only effective solution is to take control of the file ourselves.

Free PDF · the crash course

AI Agents for Marketing Crash Course

Learn how to deploy AI marketing agents across your go-to-market — the best tools, prompts, and workflows to turn your data into autonomous execution without writing code.

The Solution: Host the Google Analytics Script Locally

The best workaround is to host the Google Analytics script on your own server. This process involves grabbing a copy of the script, uploading it to your website, and then telling an updated version of your tracking code to load the script from your domain instead of Google's.

Once the file is on your server, you have full control. You can add expires headers and set the cache lifetime to a year or more, clearing the "leverage browser caching" warning and getting a better performance score.

Step 1: Download the Google Analytics Script

First, you need to get a copy of the script file. The easiest way to do this is to find the URL in your site’s source code. It will look something like this:

https://www.googletagmanager.com/gtag/js?id=GA_MEASUREMENT_ID

Paste that URL into your browser's address bar. Ignore the tracking ID part for now (?id=...). The browser will display the contents of the JavaScript file. Right-click and choose "Save As..." to save the file to your computer. A simple name like analytics.js is perfect.

Step 2: Upload the Script to Your Server

Next, you need to upload this new analytics.js file to your website's server. You can do this using an FTP client (like FileZilla) or the File Manager in your hosting provider's control panel (like cPanel or Plesk).

A good place to put it is in a dedicated script folder, like /wp-content/js/ if you're on WordPress, or a simple /js/ folder in your root directory. Make a note of the file's path - you'll need it in the next step.

Step 3: Update Your Google Analytics Tracking Code

Now you need to edit the Google Analytics tracking script that you have embedded on your site. Don't worry, this only requires changing one line.

Your original Google Universal Analytics code looks something like this:

<!-- Global site tag (gtag.js) - Google Analytics -->
<script async src="https://www.googletagmanager.com/gtag/js?id=UA-XXXXX-Y"></script>
<script>
  window.dataLayer = window.dataLayer || [],
  function gtag(){dataLayer.push(arguments),}
  gtag('js', new Date()),

  gtag('config', 'UA-XXXXX-Y'),
</script>

You need to change the src attribute to point to the local file you just uploaded. If you uploaded it to a /js/ folder, the updated code would look like this:

<!-- Global site tag (gtag.js) - Hosted Locally -->
<script async src="/js/analytics.js"></script>
<script>
  window.dataLayer = window.dataLayer || [],
  function gtag(){dataLayer.push(arguments),}
  gtag('js', new Date()),

  gtag('config', 'UA-XXXXX-Y'),
</script>

Notice the only things changed are the URL pointing to /js/analytics.js and a comment to remind yourself it's hosted locally. Make sure you keep your actual tracking ID in the code!

GraphedGraphed

Build AI Agents for Marketing

Build virtual employees that run your go to market. Connect your data sources, deploy autonomous agents, and grow your company.

Watch Graphed demo video

A Critical Consideration: Keeping the Script Updated

There's one major catch with this method: your locally hosted script is now static. It won't get any of the automatic updates, bug fixes, or new features that Google pushes to its original file. This could eventually lead to inaccurate tracking or other issues.

To solve this, you need a way to periodically refresh your local copy of the script. You can do this manually every month, but a much better solution is to automate it.

Step 4: Automate Updates with a Cron Job (Advanced)

A cron job is simply a scheduled task that runs automatically on your server. We can set up a cron job to run a script that fetches the latest version of the Google Analytics file and replaces your local copy.

Here’s a simple PHP script that does just that. Save it as a file named update-analytics.php in your site's root directory.

<?php
// Remote file to grab
$remote_file = 'https://www.googletagmanager.com/gtag/js',

// Local file to save to (make sure path is correct)
$local_file = 'js/analytics.js',

// Get remote file contents
$content = file_get_contents($remote_file),

// If we got content, save it to the local file
if ($content !== false) {
    file_put_contents($local_file, $content),
    echo "Google Analytics script updated successfully!",
} else {
    echo "Error: Could not retrieve Google Analytics script.",
}
?>

Now, log in to your cPanel, find the "Cron Jobs" icon, and create a new job. For the "Command" field, you would use something like this:

php /home/username/public_html/update-analytics.php

(Be sure to replace /home/username/public_html/ with the actual server path to your file.)

You can schedule it to run once a week or even once a day. This ensures your local script stays up-to-date automatically.

Free PDF · the crash course

AI Agents for Marketing Crash Course

Learn how to deploy AI marketing agents across your go-to-market — the best tools, prompts, and workflows to turn your data into autonomous execution without writing code.

Step 5: Add the Expires Headers

Finally, we're at the last step: telling browsers to cache our new local script. The method depends on your server type, which is usually Apache or Nginx.

For Apache Servers (using .htaccess)

If your website runs on a server like Apache, you can add caching rules to a special file called .htaccess in your root directory. Open it and add the following snippet:

<IfModule mod_expires.c>
  ExpiresActive On
  <FilesMatch "analytics\.js$">
    ExpiresDefault "access plus 1 year"
  </FilesMatch>
</IfModule>

This code tells Apache servers to add a header to the analytics.js file that instructs browsers to cache it for one year.

For Nginx Servers

If your site is on an Nginx server, you'll need to edit your server configuration file. Add a location block like this:

location /js/analytics.js {
    expires 1y,
    add_header Cache-Control "public, no-transform",
}

This tells Nginx to set an expiration time of one year for that specific file.

Easier Alternative: Use a WordPress Plugin

If all of the above feels too technical, you're in luck. For WordPress users, several plugins can automate this entire process for you with just a few clicks.

Plugins like CAOS | Host Google Analytics Locally are built specifically for this purpose. Performance optimization plugins like WP Rocket or Perfmatters also include a one-click option to host the Google Analytics script locally.

Using one of these plugins takes care of downloading the file, updating your tracking code, and setting up an automatic script a day that keeps the local copy synchronized - no manual file editing or cron jobs are needed.

Final Thoughts

Fixing the "leverage browser caching" warning for Google Analytics involves hosting the script locally so you can apply your own caching policies. By following the steps above, you can take control of the script, speed up your site, and improve your performance scores.

Wrangling tracking scripts and optimizing site speed is an important part of managing your digital presence. When you're ready to move from technical setup to getting real-time insights, tools like Graphed are there to help. We connect directly to your data sources like Google Analytics, so you can stop worrying about individual script files and start building marketing dashboards instantly using just plain English. This lets you uncover what your data means for your business without ever touching a line of code.

Related Articles