Analytics

How To:  Set Up GA4 on Multiple Environments

Multiple Envrionments

TL;DR:
If you use GA4 across production, staging and development environments, you need to prevent test activity from contaminating your live reporting without losing the ability to test analytics before launch. Depending on what you need, you can filter staging traffic, use separate GA4 properties or data streams, or use Google Tag Manager to send each hostname to a different measurement ID. This guide explains the approaches I use and when each one makes sense.

Why GA4 needs to be handled differently across environments

When I’m working as an analytics and tracking consultant, one issue I regularly need to account for is how GA4 should be configured across development, staging and production environments.

You want analytics available on your test environments so you can check page views, events, ecommerce and conversions before a site goes live.

What you don’t want is developers and testers generating data on a staging site that ends up mixed into your live reporting.

There are several ways to handle this in GA4 and Google Tag Manager, and the right approach depends on whether you want to filter non-production traffic, send it to a separate GA4 property, or manage different measurement IDs based on the hostname.

In this guide I’ll show you the approaches I use and when each one makes sense.

How to set up GA4 across staging, development and live environments

If you’re running GA4 across multiple environments, the aim is straightforward, you want to be able to test your analytics implementation on staging or development without contaminating the data you’re collecting from the live website.

For example, you might have:

  • www.example.com – live
  • staging.example.com – staging
  • dev.example.com – development

There are several ways to manage this in GA4 and Google Tag Manager. You can use the same GA4 property and control which hostname data you retain, use separate GA4 properties for live and test environments, or use GTM to send data to different measurement IDs depending on the hostname.

Which approach is best depends on how your tracking is configured and what you need to test.

Should GA4 track your staging and development sites?

Yes, in most cases I want GA4 and Google Tag Manager working on staging and development environments.

If you’re building a new website, changing an ecommerce checkout or implementing new events, waiting until the site reaches production before testing the tracking is asking for trouble.

I’ve seen sites launch with missing analytics, broken ecommerce tracking or events that appeared to work during development but weren’t actually being sent to the correct GA4 property.

Having tracking available before launch means you can test page views, events, conversions and ecommerce data while the site is still being developed.

The problem isn’t having GA4 on a staging site. The problem is allowing staging and development activity to contaminate your live reporting.

So rather than removing analytics from your test environments altogether, I prefer to keep the tracking implementation consistent and control where the data is sent or how it’s separated from production data.

This also means you’re testing something much closer to the tracking implementation that will actually be running when the site goes live.

Don’t just remove analytics from staging

It can be tempting to solve the problem by simply disabling analytics on staging altogether.

I generally don’t recommend that.

Staging is often exactly where you need analytics most: it’s where you can confirm that your events, ecommerce data, consent configuration and other tracking are working correctly before the changes reach real users.

I’d rather deliberately separate or control the data than discover after launch that something wasn’t being tracked.

Can you use one GA4 property across multiple environments?

Yes. You can use the same GA4 property across your live, staging and development environments, but that doesn’t necessarily mean you should send everything into the same reporting dataset without considering how you’ll separate the traffic.

One of the confusing things here is the difference between a GA4 property, data stream and website environment.

A GA4 property is the main container for your analytics data. Within that property you can have web and app data streams, each with its own measurement ID.

Your staging and development sites, however, don’t automatically need their own data streams simply because they’re different environments.

For example, if the same web data stream is installed on:

  • www.example.com
  • staging.example.com

GA4 can receive data from both hostnames.

Whether that’s desirable depends on what you’re trying to achieve.

If you simply want to test that GA4 is working before deployment, using the same implementation can make life easier. But if you want to retain test data without mixing it with genuine customer activity, you’ll need a way of separating the two.

That’s where hostname filtering, separate GA4 properties or routing the measurement ID through Google Tag Manager become useful.

Should you create a separate GA4 data stream for staging?

You can create another web data stream for a staging site, but I wouldn’t automatically create a new data stream for every environment.

A separate stream gives you a different measurement ID, but the data still belongs to the same GA4 property. So if your objective is complete separation between production and test data, a separate stream isn’t necessarily the same thing as having a completely separate test property.

Data Stream

I tend to start with the question “what do I want to happen to the test data?” rather than “how many data streams should I create?”

If I don’t need to retain it, filtering may be enough. If I want a clean test dataset I can inspect independently, a separate property may make more sense. And if I want the same GTM implementation to decide automatically where data should be sent, I’ll usually handle that through GTM.

How to filter staging or development hostnames in GA4

If your live and staging environments are sending data into the same GA4 property, one option is to use a Web hostname traffic data filter.

Note: Google introduced Web hostname traffic filters in August 2026 and the feature is still being rolled out. If you don’t currently see the option in your property, it may not have reached your account yet.

GA4 automatically collects the hostname for web traffic, so it can distinguish between visits to URLs such as:

www.example.com

staging.example.com

dev.example.com

A hostname filter can then be used to control which of those hostnames are included in or excluded from the data GA4 processes.

For example, if I only wanted the production website included in a GA4 property, I could configure the filter around the live hostname rather than allowing staging and development traffic into the reporting data.

In GA4, go to:

Admin → Data collection and modification → Data filters → Create filter

Data Filters

Select Web hostname traffic as the filter type.

You can then choose whether to include or exclude matching traffic, select how the hostname should be matched and enter the hostname you want the rule to apply to.

For example, if your staging environment is:

staging.example.com

you could create an Exclude filter that exactly matches that hostname, as shown below.

Create Data Filter

You’ll also notice that GA4 gives you three filter states: Testing, Active and Inactive.

I’d start with Testing rather than immediately making a new hostname filter active.

Test your hostname filter before making it active

This is one setting I’d be particularly careful with.

GA4 data filters affect incoming data from the point they’re applied. Once an exclude filter is active, the excluded data isn’t processed by GA4 and can’t simply be restored later. It also doesn’t retrospectively remove traffic you’ve already collected.

While the filter is in Testing, you can check that it’s identifying the traffic you expect before changing its state to Active.

That’s particularly important if you’re creating an include filter for your live hostname. Get the rule wrong and you could potentially stop legitimate production data from being processed.

I wouldn’t activate a hostname filter and assume it’s working. I’d verify the result before relying on it.

How to check whether your GA4 hostname filter is working

When a data filter is in Testing, GA4 doesn’t permanently exclude the matching traffic. Instead, it adds a test data filter dimension that you can use to check whether the filter is identifying the traffic you expect.

For a staging hostname filter, I’d generate some activity on the staging site and then check that GA4 is identifying those events as matching the test filter.

You can also use the Hostname dimension in an Exploration to confirm which hostname the traffic is coming from.

Once you’re satisfied that the filter is matching staging.example.com without affecting your live hostname, you can change the filter from Testing to Active.

Remember that once the filter is active, the excluded traffic will no longer be processed, so this isn’t something I’d switch on without testing first.

What happens to data GA4 has already collected?

A GA4 data filter isn’t retrospective.

If staging traffic has already been collected, creating a hostname data filter now won’t remove that historical data from the property.

You can still use the Hostname dimension in reports or Explorations to inspect or isolate traffic from particular hostnames, but that’s different from preventing the data from being processed in the first place. GA4 automatically populates the Hostname dimension for web traffic.

That’s another reason I prefer to think about environment handling when the tracking is initially configured rather than after staging traffic has already started appearing in the live property.

Should you use separate GA4 properties for staging and production?

If you want to keep your test data completely separate from your live analytics data, another option is to use a separate GA4 property for staging or development.

For example:

Example Website – Production → live website
Example Website – Test → staging/development

This gives you a clean test property where you can check events, ecommerce tracking, conversions and other changes without those interactions appearing in your production property.

I tend to prefer this approach when the staging environment is used regularly for analytics testing and I actually want to retain and inspect the test data, rather than simply exclude it.

The trade-off is that you’re now maintaining more than one GA4 property. Any relevant configuration — such as events, key events, custom dimensions or other property-level settings — may need to be kept consistent between them.

That’s why I wouldn’t create a separate property just because a staging site exists. If all I need to do is stop occasional staging traffic contaminating live reporting, a hostname filter may be enough.

If I want a persistent analytics testing environment, however, a separate property gives me much clearer separation.

Separate data stream or separate GA4 property?

These aren’t quite the same thing.

A separate web data stream gives your staging site its own measurement ID, but the stream still sits within the same GA4 property.

A separate GA4 property keeps the staging data in an entirely separate property from your production analytics.

So my decision usually comes down to:

I don’t want the staging data: filter it.

I want staging identifiable within the same property: consider a separate data stream.

I want staging data completely separated and retained for testing: use a separate property.

There’s then another option if you want the same Google Tag Manager container deployed across all of these environments: make GTM decide which GA4 measurement ID should receive the data.

Send different environments to different GA4 properties with Google Tag Manager

If you’re using separate GA4 properties or data streams for your live and staging environments, you don’t necessarily need separate Google Tag Manager containers as well.

You can use the same GTM container across multiple environments and have GTM determine which GA4 measurement ID should receive the data based on the hostname.

For example:

www.example.com → production GA4 measurement ID
staging.example.com → staging GA4 measurement ID

This is an approach I like because the tracking implementation itself can remain consistent across environments. Your tags, triggers and event configuration can be tested on staging before deployment without having to maintain two completely separate GTM containers.

One way to do this is with a Lookup Table variable.

How to use a Lookup Table for different GA4 measurement IDs

I love Lookup Tables because they have lots of uses for changing an output based on a particular input.

Let’s say I have:

www.example.com → G-PRODUCTION

staging.example.com → G-STAGING

In Google Tag Manager, create a new variable and select Lookup Table as the variable type.

Set the Input Variable to:

{{Page Hostname}}

Then add each hostname and the corresponding Google tag ID as its output.

In my own setup, for example, I have separate IDs for daveashworth.co and staging.daveashworth.co:

Once the Lookup Table is set up, I can use the variable in my Google tag rather than hard-coding a single ID.

In the example below, {{LookUp - GA4 Tracking ID}} is used as the Tag ID, with the tag firing across the site:

GTM checks the current {{Page Hostname}}, the Lookup Table returns the corresponding ID, and the Google tag sends the data to the appropriate GA4 setup.

This means I can use the same GTM container and tracking implementation on both my live and staging sites, while keeping control over where the analytics data is sent.

It also reduces the risk of somebody copying a staging site to production and forgetting to replace a hard-coded analytics ID.

What about Google Tag Manager environments?

Google Tag Manager also has an Environments feature specifically designed for testing changes across environments such as development, staging and production.

This is different from the Lookup Table approach I’ve shown above.

The Lookup Table determines which Google tag ID is used based on the hostname, whereas GTM Environments allow different versions of a container to be deployed to different environments.

You can find the feature under Admin → Environments in Google Tag Manager.

GTM includes Live and Latest as default environments, and you can create additional custom environments for development or staging.

A custom environment uses its own GTM container snippet, allowing a particular version of the container to be tested on that environment before the same changes are published to Live.

That’s potentially useful for more controlled development and release workflows, but it’s not something you need simply to send staging and production analytics to different GA4 destinations.

For the setup I’ve shown above, I’m using the hostname and Lookup Table to control that.

Which GA4 setup should you use for multiple environments?

There isn’t one GA4 setup I’d recommend for every staging, development and live environment.

It depends mainly on what you want to happen to the test data.

If I don’t need to retain staging data, a hostname filter can be enough to stop it contaminating the production property.

If I want to keep staging data completely separate so I can test events, ecommerce and other tracking without affecting live reporting, I’d consider a separate GA4 property.

If the same Google Tag Manager container is running across multiple environments, a Lookup Table based on {{Page Hostname}} is a useful way of automatically sending each environment to the appropriate Google tag ID.

And if you have a more controlled development and release process, GTM Environments provide another option for deploying different container versions to development, staging and live websites.

The important thing is to make the decision deliberately. You don’t want to discover after a launch that your production property contains weeks of staging activity — or, worse, that the tracking you tested on staging wasn’t actually the tracking running on the live site.

If you’re setting up GA4 across multiple environments and need help getting the tracking right, I can help with both analytics implementation and Google Tag Manager.

That can include checking an existing implementation, separating staging and production data, configuring events and ecommerce tracking, or making sure everything is working correctly before a new website goes live.

Please feel free to get in touch – I’m always happy to help.




About The Author

I'm Dave Ashworth, a freelance SEO and website optimisation consultant with a background in development and a focus on fixing what's broken, improving what's working, and helping businesses grow through clear, practical SEO.

I combine hands-on technical know-how with years of experience in analytics, content strategy and platform optimisation. Whether it's an audit, a migration, or ongoing performance support, my work's about making websites stronger, faster, and easier to understand for - users, search engines and AI platforms.

When I'm not writing guides or sharing insights, I'm working directly with clients to solve problems, track results, and keep their sites moving in the right direction.

Dave Ashworth

get in touch

If you need some expert website optimisation and configuration, want to find out more, or even just have a question, fill in the form below as I will always be happy to help