hello@newnorth.nl+31 (0) 85 401 31 62
/Journal

Excluding developer and internal traffic from GA4

GuideAnalytics2026.05.25
Freek Kampen
Freek KampenCo-founder, New North Digital

Staging hits, localhost sessions and your own team browsing production all land in the same property. What to filter, what to leave, and the three fixes ranked.

The problem

You open GA4 and there are 200 sessions on a URL that doesn't exist in production. Or your bounce rate dips every Monday because the marketing team is doing QA. Or there's a steady trickle from localhost.

It is not catastrophic, but left alone it inflates pageviews, distorts engagement metrics and pollutes every audience you build for retargeting.

What developer traffic actually covers

The term gets used loosely. In practice it is four things:

  • Staging. The test version of your site, often at staging.yourdomain.com or dev.yourdomain.com, where changes get QA'd before release.
  • Local development. The site on a developer's laptop, at localhost, 127.0.0.1 or something like myshop.local.
  • Internal browsing. Your own staff on the live site, from the office, from home, or while checking a campaign.
  • Automated testing. Cypress, Playwright, Lighthouse or uptime monitors hitting pages on a schedule.

If any of these load GA4 with the same measurement ID as production, those events sit in the same property as real customer behaviour.

When it is worth filtering

Not all of it needs fixing. It depends on volume and intent.

Worth filtering:

  • A staging environment with daily QA, which is tens or hundreds of sessions a week and none of it customer behaviour
  • A team of more than about five people regularly using production for support, content or campaign checks
  • Automated test runs hitting the site several times per deployment
  • A development environment firing purchase events with test data, which inflates revenue visibly

Not worth the effort:

  • The occasional stray session from a developer's laptop. A handful a month sits below the noise floor.
  • One-off audits or troubleshooting visits where you already know the impact
  • Sites under roughly 1000 sessions a month, where fixing it is fine but rarely urgent

The short version: always filter staging, since it is the biggest source; filter your office IP if you have a real office; and don't chase every stray session.

Fix one: don't load GA4 on staging at all

The cleanest fix adds no complexity to GA4 or GTM. If your developers can avoid loading the container on staging, or load a separate staging-only container, there is nothing to filter.

The usual arrangement: production loads your real container, staging loads nothing or a separate container pointing at a staging property.

Ask your developers to wrap the GTM snippet in an environment check so it only renders when the environment is production. That is a one-line change in most stacks and it removes the problem at the source.

Fix two: a hostname exception in GTM

If you cannot stop GTM loading on staging, the next best fix lives in GTM. Create a Page View trigger, Some Page Views, with the condition Page Hostname matches RegEx:

(staging|dev|test|localhost|127\.0\.0\.1)

Add it as a blocking exception on every GA4 tag, or on the Google tag itself if it is the parent of them all. When the hostname matches, nothing fires and nothing reaches GA4.

This uses built-in GTM features only. No Custom JavaScript, no extra variables, and a new staging URL means updating one regex.

Fix three: GA4 data filters as a safety net

GA4's own filters exclude traffic before it lands in reports. Useful as a second line for the cases you don't control, such as a hard-coded measurement ID someone forgot to remove.

Internal traffic. Define your office or VPN ranges under Admin, Data Streams, your stream, Configure tag settings, Define internal traffic. Then switch the built-in Internal Traffic filter to Active under Admin, Data settings, Data filters.

Developer traffic. GA4 ships a filter for events arriving with debug_mode=true. Set it to Active if you don't want DebugView events in your reports.

Two caveats: data filters apply going forward only, so they never clean history, and they are property-wide with no per-stream override. Use them to mop up edge cases, not as your main defence.

What to do this week

  1. Ask your developer whether GTM loads on staging. If it does, ask for an environment check.
  2. While that is in flight, add the hostname trigger exception in GTM as a quick win.
  3. Activate the Internal Traffic and Developer Traffic filters in GA4 to catch what gets through.

Three fixes, none needing Custom JavaScript, and they stack: the first removes the problem, the second covers what is left, the third catches the rest.

Want to talk about this?

Let's talk data.

Tell us about your stack, your goals, the data you wish you had.

Takes 1 minute