search ]

How to Self-Host Google Analytics 4 Locally for Better Page Speed

Google Analytics 4 (GA4) uses the gtag.js library, loaded from Google’s servers with a cache expiration of just two hours. Speed testing tools like Google PageSpeed Insights and GTmetrix flag this as a “Serve static assets with an efficient cache policy” issue.

Self-hosting the GA4 script on your own server gives you full control over caching headers, eliminates an external DNS lookup, and removes the warning from your speed reports. The concept is the same as loading Google Fonts locally for performance gains.

Self-hosting GA4’s gtag.js locally reduces third-party requests, eliminates DNS lookups to Google’s servers, and lets you set your own browser caching headers for better PageSpeed scores.

Why Host GA4 Locally?

Google sets the cache expiration on gtag.js to just two hours. The recommended minimum is at least one week, which is why every major speed testing tool flags it.

By hosting the file on your own server, you can set cache headers to a year or more. Repeat visitors load the script from their browser cache instead of making a new request to Google.

Self-hosting also eliminates the DNS lookup and TLS handshake to www.googletagmanager.com. While the actual time savings are small, it removes the dependency on an external server and cleans up your performance reports.

The real-world speed improvement from self-hosting GA4 is minimal. This optimization mainly removes warnings from speed testing tools. It’s up to you whether the maintenance is worth it. Performance plugins like WP Rocket and LiteSpeed Cache can handle this automatically.

How to Self-Host GA4’s gtag.js

Here’s how to manually download and serve GA4’s tracking script from your own server. You’ll also set up an automatic update via a cron job to keep the file current.

Step 1 – Download the Script

Open the following URL in your browser, replacing G-XXXXXXX with your actual GA4 Measurement ID:

https://savvy.co.il/wp-content/litespeed/localres/aHR0cHM6Ly93d3cuZ29vZ2xldGFnbWFuYWdlci5jb20vZ3RhZy9qcw==?id=G-XXXXXXX

Copy the entire content and save it as local-gtag.js. Upload this file to your server root via FTP, for example to /public_html/local-gtag.js.

Step 2 – Update Your Tracking Code

Replace the standard GA4 tracking snippet with a version that points to your local file:

<script async src="https://example.com/local-gtag.js"></script>
<script>
  window.dataLayer = window.dataLayer || [];
  function gtag(){dataLayer.push(arguments);}
  gtag('js', new Date());
  gtag('config', 'G-XXXXXXX');
</script>

Replace https://example.com/local-gtag.js with the actual URL on your domain, and change G-XXXXXXX to your GA4 Measurement ID.

Step 3 – Create the Auto-Update Script

Google updates gtag.js frequently. To keep your local copy current, create a PHP file named update-gtag.php with the following code:

<?php
$measurement_id = 'G-XXXXXXX';
$remote_url     = "https://savvy.co.il/wp-content/litespeed/localres/aHR0cHM6Ly93d3cuZ29vZ2xldGFnbWFuYWdlci5jb20vZ3RhZy9qcw==?id={$measurement_id}";
$local_file     = __DIR__ . '/local-gtag.js';

$context = stream_context_create([
    'http' => [
        'timeout'    => 15,
        'user_agent' => 'Mozilla/5.0',
    ],
]);

$content = @file_get_contents( $remote_url, false, $context );

if ( $content && strlen( $content ) > 1000 ) {
    file_put_contents( $local_file, $content );
    echo "Updated successfully. Size: " . strlen( $content ) . " bytesn";
} else {
    echo "Download failed or file too small. Keeping existing version.n";
}
?>

Change G-XXXXXXX to your GA4 Measurement ID. The script verifies the downloaded file is larger than 1KB before overwriting, which prevents saving an error page over your working script.

Step 4 – Set Up a Cron Job

Upload update-gtag.php to the same directory as local-gtag.js. Then create a cron job to run it once a day.

In cPanel, go to Cron Jobs, set it to Once Per Day, and add the following command:

/usr/bin/php /home/username/public_html/update-gtag.php >/dev/null 2>&1
Setting up a Cron Job in cPanel to update the Google Analytics script

Adjust the path /home/username/public_html/ according to your server setup. The cron job downloads the latest version of gtag.js from Google every 24 hours and saves it locally.

Self-Hosting GA4 on WordPress

If you’re running Google Analytics 4 on WordPress, several plugins automate the entire process. They download gtag.js to your server and use WordPress’ built-in wp_cron to keep it updated.

CAOS (Complete Analytics Optimization Suite)

The free CAOS plugin has supported GA4 since version 3.8. Enter your Measurement ID (G-XXXXXXX), and the plugin handles everything – local hosting, automatic updates, and optional features like Stealth Mode and Minimal Analytics 4 (which also resolves the “Reduce unused JavaScript” warning).

Performance Plugins with Built-in Support

Several popular performance plugins include local analytics hosting as a feature:

  • WP Rocket – Toggle “Host Google Analytics locally” in the File Optimization settings
  • Perfmatters – Enable under the Scripts tab with automatic daily updates
  • FlyingPress – Self-hosts all third-party scripts including GA4
  • LiteSpeed Cache – Includes a local GA hosting option in the Page Optimization settings

If you’re already using one of these plugins, check their settings before installing CAOS. You likely don’t need both.

Server-Side GTM – The Advanced Alternative

For sites that need maximum performance and data accuracy, server-side Google Tag Manager is the most modern approach. Instead of loading gtag.js in the browser, tracking requests are routed through your own server.

Benefits of server-side tagging include:

  • Near-zero client-side performance impact since scripts run on your server
  • First-party cookies that bypass Safari’s ITP and Firefox tracking restrictions
  • Better data accuracy because ad blockers can’t intercept server-to-server requests
  • Improved GDPR compliance by processing data on your own infrastructure

The trade-off is complexity and cost. Server-side GTM requires a cloud server (Google Cloud, AWS, or managed services like Stape.io) and more technical setup. For most WordPress sites, self-hosting gtag.js locally is the simpler option that still delivers meaningful results.

If your site receives significant traffic from Safari or Firefox users, server-side tagging can extend cookie lifetimes from 7 days to up to 2 years. This prevents returning visitors from being counted as new users and significantly improves data accuracy in GA4.

FAQs

Common questions about hosting Google Analytics 4 locally:

Does Google support self-hosting gtag.js?
Google does not officially recommend self-hosting gtag.js, mainly because they update the file frequently with bug fixes and features. However, if you set up an automatic cron job to update the local copy daily, the practical risk is very low. Many performance-focused sites have used this approach for years without tracking issues.
Will self-hosting GA4 affect my tracking data accuracy?
As long as your cron job runs daily and the local file stays up to date, there should be no difference in data accuracy. The gtag.js library sends data to Google's collection servers regardless of where it's loaded from. The only risk is if your cron job fails silently and the local file becomes very outdated.
What is the difference between self-hosting gtag.js and server-side GTM?
Self-hosting gtag.js means you serve the JavaScript file from your domain instead of Google's, but tracking still happens in the visitor's browser. Server-side GTM routes the tracking data through your own server before sending it to Google. Server-side tagging provides better ad-blocker resistance and extended cookie lifetimes, but requires a dedicated cloud server and is more complex to set up.
Can I use this method with Google Tag Manager?
Yes, but the approach is different. If you load GA4 through Google Tag Manager, you would need to self-host the GTM container script (gtm.js) rather than gtag.js. The CAOS plugin and some performance plugins can handle this automatically. If you load GA4 directly without GTM, the method described in this post applies.
How much faster will my site be after self-hosting GA4?
The measurable speed improvement is typically negligible - a few milliseconds at most. The main benefit is eliminating the "Serve static assets with an efficient cache policy" warning in PageSpeed Insights and similar tools. If your goal is actual load time reduction, focus on larger optimizations like image compression, render-blocking resources, and server response time first.
Is the old analytics.js method still relevant?
No. Google shut down Universal Analytics in July 2023 and the analytics.js library no longer sends data. All websites must use GA4 with gtag.js. If you were previously self-hosting analytics.js, you need to remove it and switch to the GA4 method described in this post.

Summary

Self-hosting Google Analytics 4’s gtag.js locally is a straightforward optimization that eliminates third-party caching warnings from your speed reports. The real-world speed gain is minimal, but it gives you full control over the script’s delivery.

For non-WordPress sites, download gtag.js, set up a daily cron job to keep it updated, and point your tracking code to the local file. For WordPress sites, use CAOS or the local analytics feature in your existing performance plugin.

If you need maximum performance and data accuracy, consider server-side Google Tag Manager as a long-term investment. It moves tracking entirely off the client side and provides benefits well beyond caching.

Join the Discussion
7 Comments  ]
  • Michael Bay 2 November 2024, 18:02

    Is this still working? Can’t find my UA number, and it seems that google tag manager overrides all now a days? Is that correct?

    • רועי יוסף 2 November 2024, 18:04

      Hi Michael,

      You are correct, i need to update the post. Thanks for letting me know, i will update it asap..

  • Michael 5 November 2024, 22:43

    Hi Roee

    Thanks for quick answer. So, right now there is no option for local hosting of google tag manager? I would love for an option 😀

    • רועי יוסף 5 November 2024, 22:47

      I currently don’t know an option unless you are using LiteSpeed Cache plugin which have that option built in. I will notify you when i’ll find a solution though.. 🙂

  • Michael 8 November 2024, 11:30

    Ohh really? I haven’t found that solution with Litespeed Cache plugin. If this is in WordPress you refer to?

    I got to check that out. This project I was working on, was just static HTML pages.

  • Michael 8 November 2024, 12:49

    WOW! I did not know that. I have just set that ON to my personal page. I can see the scripts are loading local, and no 3. part URL’s.

    Thanks for telling me this. Haven’t seen that 😀

    Now I just wonder why google page speed still says that its hosted from Google, and no Local. But maybe I need to wait 24 hours for cache on pagespeed to be loaded

    Again. Thanks!

Leave a Comment

To add code, use the buttons below. For instance, click the PHP button to insert PHP code within the shortcode. If you notice any typos, please let us know!

Savvy WordPress Development official logo