The State of Google Tag Manager in B2B SaaS
We scanned ~2,000 publicly accessible Google Tag Manager containers from B2B SaaS websites using TagManifest's scanning engine. Every container was parsed from Google's public gtm.js endpoint. We also ran page-level scans to detect consent tools and tracking scripts loaded outside GTM.
This is a snapshot of how B2B SaaS configures its measurement infrastructure in April 2026.
Top findings
1. 56% of B2B SaaS sites have no consent management detected anywhere. No CMP on the page, no CMP in GTM. Among the 44% that do have a CMP, most deploy it outside GTM via inline scripts, which is the correct approach. But more than half the market has nothing, and 20 US states now have active privacy laws.
2. 26% of sites load gtag.js both through GTM and independently on the page. One in four B2B SaaS sites has dual Google Analytics implementations, risking duplicate page views, inflated sessions, and unreliable conversion data. This is likely a legacy pattern: Google merged the gtag.js and GTM deployment paths in September 2023, but the old hardcoded scripts were never removed.
3. 80% of Custom HTML tags have no consent configured. Native Google tag templates enforce consent at 100% (the template requires it). Custom HTML defaults to NOT_SET and stays there. Across 28,546 Custom HTML tags in the dataset, only 20% have consent categories configured.
4. GA4 click tracking uses 8 or more event names. cta_click, click, button_click, link_click, menu_click, nav_click, navigation_click, internal_link_click. No naming consensus exists in B2B SaaS. Google's recommended event name for lead forms (generate_lead) is used by only 9% of containers.
5. 4,432 Universal Analytics tags are still executing, three years after Google sunset the platform. These tags fire on every page load, send network requests, and the data is discarded on arrival. Nobody went back to clean them up.
6. Meta Pixel is 40% community template, 60% Custom HTML. Migration to the community template is happening, but the majority of Meta implementations still use pasted fbq() JavaScript with no built-in consent enforcement and no sandboxed execution.
7. Every additional 50 tags costs roughly 3 health points. The relationship between container size and health score is linear with no sharp threshold. A 200-tag container scoring 67 may be better maintained than a 10-tag container scoring 90. Complexity degrades health gradually, not catastrophically.
How we collected this data
TagManifest parses GTM containers from Google's public gtm.js endpoint, the same JavaScript file served to every visitor on every page load. This gives us every tag, trigger, variable, consent setting, GA4 event, ad platform configuration, and Custom HTML code block. Variable references survive the compilation process (validated against full JSON exports). Built-in trigger IDs do not, which means we suppress 4 rules that depend on trigger identification and note this as a limitation throughout.
Early in this research, we scanned containers in isolation and realized quickly that consent findings were incomplete without page-level context. A container can show "no CMP" while the site has OneTrust loading in the page source before GTM. So we added page-level scanning to check for CMP scripts, tracking loaded outside GTM, and consent defaults set before the container fires. This combination of container analysis and page scanning gave us a more complete picture, and it's something we're considering adding to TagManifest as a product feature.
We validated our public endpoint detection accuracy against full JSON exports for containers where we had both. The diagnostics we're confident in are reliable. The ones we're not confident in (trigger-specific detections) are excluded from this report. Some findings here are definitive (tag types, consent settings, Custom HTML code patterns). Others are indicative of market patterns without being individually conclusive (whether a specific configuration is intentional or accidental, whether Enhanced Measurement is enabled alongside a manual tag).
The typical B2B SaaS container
The median container has 43 tags and scores 76 out of 100 on TagManifest's health metric. Half the market sits at the boundary between our B and C grades.
| Metric | Value |
|---|---|
| Median tags | 43 |
| Mean tags | 61 |
| Median health score | 76 |
| GA4 adoption | 93% |
| Containers with Custom HTML | 89% |
| Containers with paused tags | 69% |
Across all 1,990 containers, the tag type breakdown shows what B2B SaaS puts in GTM:
| Tag type | Total tags |
|---|---|
| Custom HTML | 28,546 |
| GA4 Event | 28,373 |
| Google Ads Conversion | 8,837 |
| Universal Analytics | 4,432 |
| Microsoft UET | 3,850 |
| Google Tag | 3,852 |
| Floodlight | 2,032 |
| Conversion Linker | 1,646 |
| Google Ads Remarketing | 1,122 |
| LinkedIn Insight | 848 |
Custom HTML (28,546 tags) and GA4 events (28,373) are nearly tied as the dominant tag types. Universal Analytics persists at 4,432 tags, three years after Google sunset the platform in July 2023.
Container size and health
Larger containers consistently score lower on our health metric.
| Size | Containers | Mean score |
|---|---|---|
| 1-10 tags | 301 | 90 |
| 11-25 tags | 376 | 80 |
| 26-50 tags | 455 | 76 |
| 51-100 tags | 489 | 72 |
| 101-200 tags | 283 | 70 |
| 200+ tags | 86 | 67 |
Every additional 50 tags costs roughly 3 health points. There's no cliff where containers break. Entropy accumulates gradually.
The relationship is worth interpreting carefully. We can't determine from the public endpoint why a container is large. It may be large because the measurement requirements are complex (multiple products, multiple user journeys, multiple ad platforms). It may be large because tags have accumulated over years without anyone cleaning up. What we can see is the types of findings that emerge at scale: more optimization findings at higher tag counts (more ad platforms to configure, more Custom HTML to maintain, more triggers to organize), but not meaningfully more error-tier findings. Large containers accumulate debt, not danger.
A 200-tag container scoring 67 may be better maintained than a 10-tag container scoring 90. The smaller container simply has less surface area for patterns to emerge. We label containers with fewer than 10 tags as "Emerging" rather than assigning a letter grade for this reason.
Consent comes first
We're putting consent early in this report because it's the finding with the most immediate practical implications, and because it required the most methodological care to get right.
The container-only view is incomplete
TagManifest is a container scanning tool. When we look at consent from inside the container only, 87% of containers show "no CMP detected." That number is misleading. Consent Management Platforms like OneTrust and Cookiebot recommend deploying via inline scripts in the page source before GTM loads, not as a tag inside GTM. Google's own Consent Mode documentation recommends the same approach: set consent defaults before any tags fire.
This means a container-only scan will over-report consent gaps. We discovered this early in the research and added page-level scanning to get the actual picture.
The actual consent picture
| What we checked | CMP found | Share |
|---|---|---|
| Page HTML (inline scripts) | 842 / 2,081 | 40% |
| Inside GTM container | 193 / 1,990 | 10% |
| Either source | 879 / 1,990 | 44% |
| Neither | ~1,111 | ~56% |
40% of B2B SaaS sites have a CMP on the page. Most deploy it outside GTM, which is the correct approach. OneTrust (34% of CMP deployments) and Cookiebot (31%) dominate the market. CookieYes (18%) has emerged as a third option, particularly among smaller companies.
56% have no CMP detected on the page or in GTM. For US-focused B2B SaaS, this has historically been treated as a business decision, but the regulatory landscape is shifting. 20 US states now have active privacy laws. 12 require honoring Global Privacy Control signals. Google's own Consent Mode deadline (July 2025) requires compliant consent management for Google Ads accounts. The 56% without a CMP isn't a comfortable number to sit with going forward.
The configuration gap
Inside GTM containers, consent configuration splits cleanly along structural lines:
| Tag type | Consent configured |
|---|---|
| Native Google tags (GA4, Ads, UET, Floodlight, Linker) | 100% |
| Custom HTML (28,546 tags) | 20% |
| Universal Analytics (4,432 tags) | 5% |
Native GTM tag templates require consent configuration during setup. The 100% is template enforcement, not human diligence. Custom HTML has no such enforcement. The consent settings section exists but defaults to NOT_SET, and 80% of Custom HTML tags remain at that default.
That 80% is an immediate audit item for any consultant or in-house analytics professional. Custom HTML can be anything: a form listener, a vendor pixel, a chat widget, a configuration snippet. Each tag needs individual evaluation for whether consent should be configured. When we're looking at 28,000 Custom HTML tags across 2,000 containers, that's a significant volume of tags that have never been evaluated for consent.
This is the nature of consent work: it's a moving target. Every new Custom HTML tag, every new vendor integration, every new tracking script potentially needs consent configuration. Having consent management as part of the workflow (not a one-time setup) is where the industry needs to get to.
Consent correlates with advertising maturity
| Ad platforms in container | CMP detected | Rate |
|---|---|---|
| 0 | 92 / 318 | 29% |
| 1 | 130 / 413 | 31% |
| 2 | 160 / 438 | 37% |
| 3 | 190 / 421 | 45% |
| 4+ | 307 / 534 | 57% |
Companies running more ad platforms are more likely to have a CMP. More ad platforms means more data flowing to more third parties, which increases compliance pressure. The Google Ads consent requirement alone may explain part of the correlation at the 3-4 platform level.
GA4 is universal but the migration isn't finished
93% of containers have GA4. But the data tells a more nuanced story about maturity than adoption.
Event naming has no consensus
We cataloged every GA4 event name across 1,990 containers. Click tracking alone uses 8 or more variants:
| Event name | Containers |
|---|---|
| cta_click | 108 |
| click | 96 |
| link_click | 69 |
| button_click | 66 |
| menu_click | 35 |
| navigation_click | 31 |
| nav_click | 25 |
| internal_link_click | 29 |
Form tracking fragments in the same way: form_submit (139), form_submission (83), generate_lead (170), plus tool-specific variants (hubspot_form_submit, marketo_form_submit, pardot_form_submit). A team running HubSpot might have four separate events tracking the same form submission.
Part of what's happening here is a tension in GA4's data model. GA4 encourages using top-level event names with parameters to distinguish subtypes (e.g., click with a click_type parameter for "cta", "menu", "nav"). But parameters require configuring custom dimensions in GA4's admin before they appear in reports, which adds a step most teams skip. The result is that teams encode the distinction in the event name itself (cta_click, menu_click, nav_click), creating fragmentation at the event level instead of organizing it at the parameter level.
Google publishes a list of recommended events that unlock out-of-the-box audiences and predictive metrics. The recommended name for B2B lead forms is generate_lead. Only 170 containers (9%) use it.
8% of containers fire GA4 events with {{Event}} as the event name. This is a GTM variable that passes through whatever the dataLayer event name is. It's not unpredictable in practice: containers using this pattern are likely routing dataLayer events through a consistent naming system, and the {{Event}} variable ensures the GA4 event name matches the dataLayer event name exactly. If anything, this pattern indicates a more deliberate implementation, not a less deliberate one.
Enhanced Measurement overlap
27% of containers have manual GTM tags that duplicate events GA4 collects automatically through Enhanced Measurement:
| Enhanced Measurement event | Containers with manual duplicate |
|---|---|
| page_view | 118 |
| click (outbound) | 114 |
| scroll | 85 |
| form_submit | 79 |
| file_download | 45 |
Google's guidance is to disable the relevant Enhanced Measurement toggles for any event tracked manually via GTM. But the overlap isn't always accidental. Enhanced Measurement's form submission detection relies on native HTML form events and doesn't work reliably with AJAX forms or marketing automation platforms. When working with HubSpot, Marketo, or Pardot forms, the validated form submission comes from the API response, not from the browser's form submit event. Configuring a manual tag for that scenario is correct, even if it creates overlap with EM's form tracking. The question is whether the EM toggle was also disabled, which we can't determine from the container.
Parameter quality tells the migration story
The most common custom GA4 parameters reveal how the industry migrated from Universal Analytics:
| Parameter | Instances | What it tells us |
|---|---|---|
| event_category | 1,241 | UA mental model persists |
| event_label | 1,258 | UA mental model persists |
| event_action | 976 | UA mental model persists |
| page_path | 1,290 | Automatically collected by GA4 |
| page_url | 930 | Automatically collected |
| gtm_tag_name | 1,336 | Debug parameter in production |
event_category, event_label, and event_action are Universal Analytics concepts. GA4 doesn't use this model at all. These parameters work as custom dimensions but they consume the 25-parameter-per-event limit without mapping to GA4's native reporting structure. Seeing them in 1,241 containers suggests that the GA4 migration was structural (tags were reconfigured) but not conceptual (the data model wasn't rethought).
From my own experience managing these migrations, this tracks. The GA4 migration was done under pressure (the July 2023 deadline was relatively sudden for the scale of changes required), and the path of least resistance was to carry over the UA event structure into GA4 parameters. It worked. The data flowed. But the conceptual shift from a session-based, category/action/label model to an event-based, parameter-driven model didn't happen for many teams.
page_path and page_url appearing in 1,290 and 930 instances is a different issue. GA4 automatically collects page_location, page_referrer, page_title, language, and screen_resolution on every event. Manually adding these as custom parameters is redundant and wastes parameter slots that could carry business-specific data.
gtm_tag_name appearing 1,336 times is a debugging parameter. It records which GTM tag fired the event. It's useful during development but in production it adds noise to GA4 reports and BigQuery exports. Its prevalence at this scale suggests that GTM containers, despite being the central mechanism for so much web analytics, tend to be somewhat neglected after initial setup. Tags get configured, they work, and the container isn't revisited until something breaks.
The B2B conversion funnel
The top non-default GA4 events reveal the B2B SaaS funnel: generate_lead (170) to form_submit (139) to sign_up (94) to demo_request (58) to purchase (118). B2B-specific events that don't appear in Google's recommended event list include demo_request, webinar_registration (11), and content_download (15).
ABM and personalization tools write events into GA4: 6sense (company_details_6si, 39 containers), Mutiny (experience_impression, 23), VWO (23), and Navattic (17). These platforms use GA4 as a shared measurement layer. The 6sense implementation is notable for having two different event name patterns across the dataset (company_details_6si and 6si_company_details_loaded), fragmentation even within a single vendor's recommended implementation.
The ad platform stack
| Platform | Containers | Share |
|---|---|---|
| Google Ads | 1,440 | 72% |
| 919 | 46% | |
| Meta/Facebook | 802 | 40% |
| Microsoft Ads | 738 | 37% |
| Floodlight (CM360) | 181 | 9% |
| Twitter/X | 121 | 6% |
| 117 | 6% |
LinkedIn at 46% is the second platform after Google Ads. In broader web patterns, Meta dominates the #2 position, but this is a B2B dataset and LinkedIn's position here reflects a shift that's visible across B2B marketing. The median container runs 3 ad platforms.
Meta Pixel implementation
Meta doesn't have a first-party GTM integration. Two implementation paths exist: a community template in the GTM Template Gallery, and Custom HTML (the fbq() JavaScript snippet).
Across 802 containers with Meta Pixel:
- 40% use the community template (1,919 tags)
- 60% use Custom HTML (2,903 tags)
The distinction matters for consent and security. Custom HTML Meta Pixel tags run with full page access outside GTM's sandbox and have no built-in consent enforcement. Community templates can enforce consent through GTM's consent framework and operate within a sandboxed environment. Simo Ahava's guidance is that Custom HTML should be used "only when absolutely necessary."
The 40% community template adoption shows migration is happening. The 60% still on Custom HTML likely reflects implementations that predate the community template's availability, and the reality that a working Custom HTML pixel doesn't generate urgency to migrate.
LinkedIn shows a similar pattern at 35% native vs 65% Custom HTML. Microsoft Ads is 100% native, likely because its GTM tag type has been built into GTM's tag type menu (not the community gallery) for longer.
Tracking outside GTM
47% of the scanned pages load tracking scripts independently of GTM.
| Script | Sites | Share |
|---|---|---|
| gtag.js | 540 | 26% |
| HubSpot | 364 | 17% |
| Clarity | 172 | 8% |
| 171 | 8% | |
| Meta Pixel | 138 | 7% |
| Hotjar | 127 | 6% |
26% of sites with GTM also load gtag.js directly. This is likely a legacy pattern. Google introduced the Google Tag as a tag type inside GTM in September 2023, combining what used to be two separate deployment paths (gtag.js for direct implementation, GTM for tag management). Before that consolidation, teams often had both: gtag.js added by a developer to the site template, and GA4 configured inside GTM by a marketing team. Three years later, both are still running on 1 in 4 sites, with the risk of double-counting page views, inflating session counts, and producing artificially low bounce rates.
HubSpot at 17% is the second most common independently loaded script. HubSpot's CMS integration deploys its own tracking code automatically. In some cases, HubSpot appearing on the page alongside GTM is intentional and valid, particularly when HubSpot is used for form listeners or other CMS-specific functionality. But it's worth checking whether HubSpot is also configured inside GTM, which would create redundant tracking.
What sites without GTM look like
934 non-GTM B2B SaaS sites were scanned separately. 65% have no detectable client-side tracking at all. Many of these are developer-focused tools that either don't track or use server-side analytics. Among the 35% that do track, gtag.js loaded directly is the most common approach. Segment (40 sites) and Tealium (21 sites) represent the alternative tag manager segment.
Custom HTML
89% of containers have at least one Custom HTML tag. The mean is 14.3 per container. These are hand-written JavaScript blocks running with full page access and no sandboxing.
We analyzed code patterns across all Custom HTML tags:
| Pattern | Tags |
|---|---|
| Loads external scripts | 11,174 |
| Manipulates the DOM | 6,525 |
| Pushes to dataLayer | 3,364 |
| Adds event listeners | 1,913 |
| Reads cookies | 1,458 |
| Uses jQuery | 459 |
| Uses document.write | 62 |
| Uses eval() | 4 |
Tags may match multiple patterns. Approximately 21% matched no classification.
11,174 Custom HTML tags load external JavaScript files. Each bypasses GTM's tag management by injecting unmanaged scripts into the page. The most common: Meta Pixel (connect.facebook.net/fbevents.js, 1,102 instances) and LinkedIn (window.lintrk, 1,430 instances).
19% of containers contain Custom HTML with obfuscated or minified code that can't be meaningfully reviewed through static analysis. These are vendor-provided snippets pasted verbatim into GTM. Nobody opened the tag after the initial setup, and nobody can tell what the code does without deobfuscating it first.
Legacy code persists
Google sunset Universal Analytics in July 2023. Three years later, 4,432 UA tags exist across this dataset. Only 5% have consent configured. These tags push events to properties that Google no longer processes. The JavaScript executes, the network request fires, and the data is discarded on arrival.
This finding is, honestly, a little painful to see. The GA4 migration was one of the more difficult migrations in recent MarTech history. It was foisted upon teams with a relatively sudden deadline, and the January-to-July 2023 period was some of the busiest consulting work many of us experienced. Tags were migrated, events were reconfigured, and then the container was closed and nobody went back to check.
Seeing UA tags persist three years later speaks to a broader pattern: GTM containers are additive systems. Tags get added but rarely removed. Paused tags (69% of containers, averaging 10 per container) are the mild version of this. Active UA tags sending data to dead endpoints are the extreme version. Both reflect the same dynamic: nobody has the confidence or the mandate to remove things from a container that's currently working.
7% of containers have code from before Universal Analytics entirely: _gaq.push() calls from Google's ga.js library (pre-2014) and __utmz cookie reads. Three generations of Google Analytics code coexist in these containers.
Limitations
This report is based on static analysis of publicly accessible GTM containers and homepage HTML. It is not a compliance assessment, performance audit, or security scan.
We can see what's configured. We can't see why it's configured that way, whether it fires correctly at runtime, or whether configurations that look like mistakes are intentional decisions we don't have context for.
Specific limitations:
- Built-in trigger IDs (All Pages, Consent Initialization) are transformed during
gtm.jscompilation. Four rules that depend on trigger identification are suppressed. - Server-side tracking is invisible to this analysis. Companies with server-side GTM may have measurement infrastructure we can't detect.
- CMP configuration beyond presence/absence is not assessed. We detect that a CMP exists, not how it's configured or whether it's working correctly.
- Geo-gated CMPs (showing only to EU visitors) would be invisible on a homepage scan from a single location.
- This is a convenience sample of B2B SaaS companies from English-language software directories. It skews toward companies with established marketing websites. Different populations (ecommerce, enterprise, regional markets) would produce different patterns.
- Our health scoring is TagManifest's metric, not an industry standard. No agreed-upon grading scale exists for GTM containers. The methodology and all rule definitions are documented at tagmanifest.com/audit-checks.
We evolved this research from an initial scan of ~600 containers, through several expansions, to the current ~2,000. At each stage, we discovered limitations in our methodology and addressed them. The most significant was adding page-level scanning after realizing that container-only consent findings had a 39% false alarm rate because CMPs deploy outside GTM. Each iteration made the analysis more honest. There are certainly limitations we haven't yet identified.
Key numbers
| Finding | Stat |
|---|---|
| GTM adoption in B2B SaaS | 63% of 3,205 sites |
| GA4 adoption among GTM users | 93% |
| Median container size | 43 tags |
| CMP on page | 40% |
| No CMP detected anywhere | ~56% |
| Tracking outside GTM | 47% of pages |
| Double gtag.js loading | 26% |
| Meta Pixel: community template vs Custom HTML | 40% / 60% |
| Enhanced Measurement overlap | 27% |
| GA4 click event naming variants | 8+ |
| GA4 generate_lead adoption | 9% |
| Native tag consent configured | 100% |
| Custom HTML consent configured | 20% |
| Universal Analytics tags still present | 4,432 |
| Health score penalty per 50 additional tags | ~3 points |
Data collected April 2026. ~2,000 GTM containers scanned via public endpoint. ~2,100 homepage scans. Convenience sample of B2B SaaS companies. Scanning engine: TagManifest (tagmanifest.com). All findings are observations about configuration patterns.