Google Analytics 4
Built for
B2B SaaS
Revenue.
Out-of-the-box GA4 tracks sessions and page views. That tells you nothing about CAC. We implement GA4 with a B2B SaaS event taxonomy, server-side tagging via GTM, and Measurement Protocol CRM integration — so you can see which channel produced which closed deal.
Browser (your B2B SaaS app)
Single GTM container tag fires
GTM Server Container
Google Cloud · your subdomain
GA4
Full event data
Google Ads
Conversion import
CRM (HubSpot / Salesforce)
Closed-won → Measurement Protocol → GA4
What your GA4 is
missing right now
Default GA4 installed via a snippet or basic GTM setup tracks almost nothing useful for B2B SaaS. Here are the six gaps we find in every audit.
01
Tracking page views, not conversions
Default GA4 fires a page_view event. It does not fire when someone requests a demo, completes a trial signup, activates a feature, or books a call. Without custom events, you have no conversion data — just traffic data.
02
No CRM attribution
GA4 session ends when the user books a demo. The deal closes 30 days later in HubSpot. Without Measurement Protocol integration, GA4 never knows that deal closed — so you can't calculate true CAC or attribute revenue to the channel that sourced the deal.
$0 revenue visible in GA403
Ad blocker data loss
Client-side GA4 tags are blocked by Safari ITP, Firefox Enhanced Tracking Protection, Brave, and most ad blockers. For B2B SaaS with a tech-savvy ICP, up to 35–40% of your conversion events never reach GA4 — understating every channel's performance.
Up to 38% data loss04
Broken UTM attribution
When your outbound email prospect visits your site, books a demo, and returns 5 days later directly — last-touch attribution credits "direct" with the conversion. The outbound email that generated the interest gets zero credit. Your CAC calculation is wrong.
Last-touch misattributes ~60%05
No funnel stage visibility
Without event tracking at each stage — trial signup → onboarding completion → first value moment → payment — you can't identify where your funnel is leaking. Most B2B SaaS companies lose 70% of trials between signup and first meaningful action. That leak is invisible in default GA4.
~70% trial drop-off invisible06
Page speed impact from client-side tags
A typical B2B SaaS site fires 8–15 third-party tags client-side: GA4, Google Ads, LinkedIn Insight, Meta Pixel, HubSpot, Intercom, etc. Each adds 80–200ms latency. Combined, they can add 1–2 seconds to LCP — directly hurting ad Quality Scores and organic rankings.
1–2s LCP impactThe complete GA4
stack for B2B SaaS
Four interconnected layers — each one adds a capability the others depend on. Skip any layer and the model breaks.
GA4 Property Setup
A correctly configured GA4 property with data streams, enhanced measurement selectively enabled, and data retention set to 14 months. Google Signals enabled for cross-device reporting. BigQuery export connected for raw event data access.
- GA4 property + web data stream configured
- Enhanced measurement: scroll, outbound clicks only
- Google Signals for cross-device attribution
- BigQuery export for raw event analysis
- Data retention: 14 months (max)
- Conversion events defined and marked
GTM Web + Server Container
A GTM web container fires a single first-party request to your GTM server container (hosted on Google Cloud at analytics.yourdomain.com). The server container routes enriched events to GA4, Google Ads, LinkedIn, and Meta — bypassing ad blockers entirely.
- GTM web container with B2B SaaS tag architecture
- GTM server container on Google Cloud Run
- Custom subdomain (first-party cookie)
- GA4 client + tag in server container
- Google Ads conversion tag via server
- LinkedIn, Meta tags via server (no client JS)
B2B SaaS Event Schema
A 12-event taxonomy mapped to every stage of the B2B SaaS buyer journey — from first ad click to closed-won. Every event carries UTM parameters from the original acquisition source, persisted in a first-party cookie across sessions.
demo_requested— form submit or calendar link clickdemo_completed— post-call CRM webhooktrial_started— signup confirmationtrial_activated— first meaningful product actionpayment_initiated— billing page reachedsubscription_started+closed_won
Measurement Protocol + CRM
When a deal closes in HubSpot or Salesforce, a CRM webhook fires to a Cloud Function which sends a closed_won event to GA4 via the Measurement Protocol — carrying the original session's client ID, UTM parameters, and deal value. Complete closed-loop attribution.
- HubSpot / Salesforce deal closed-won webhook
- Cloud Function processes deal data
- Measurement Protocol sends to GA4 API
client_idmatched from CRM contact property- Original UTM source preserved to revenue
- Looker Studio: CAC per channel from real data
Client-side vs server-side:
what actually changes
Most B2B SaaS companies run all their tracking client-side. Here's what that means in practice — and what changes when you move to server-side.
8–15 JS tags fire in browser
GA4, Google Ads, LinkedIn Insight, Meta Pixel, HubSpot, Intercom, Hotjar all loaded as separate scripts from third-party servers.
Ad blockers block 30–40% of events
Safari ITP, Firefox ETP, Brave, and ad blocker extensions intercept and block third-party tracking requests — silently dropping conversion events.
Third-party cookies expire in 7 days
Safari limits third-party cookie lifetime to 7 days via ITP. Cross-session attribution breaks. A prospect who takes 2 weeks to convert looks like a "direct" visit.
Page speed impact: +1.2s LCP
Each client-side tag adds DNS lookups, TCP connections, and script execution. Combined: 800ms–1.5s of additional page load time.
Underreported Google Ads conversions
Missing 30–40% of conversion events means Google's Smart Bidding algorithms are trained on incomplete data — bidding suboptimally and raising your effective CPL.
1 GTM tag fires in browser
A single first-party request goes to your GTM server container at analytics.yourdomain.com. The server container distributes to all downstream tools.
Ad blockers can't block first-party requests
The request goes to your own subdomain — browsers and ad blockers treat it as a first-party resource. Data loss drops from 35% to under 3%.
First-party cookies set server-side
The server container sets _ga as a server-side first-party cookie — exempt from ITP restrictions. Attribution window extends to 400 days.
Page speed: −0.8s LCP improvement
Removing 7–14 client-side tags eliminates most DNS lookups and third-party script execution. LCP typically improves 0.6–1.2 seconds.
Google Ads gets complete conversion data
Full conversion signal fed into Smart Bidding. Google's algorithm trains on accurate data — CPL typically drops 15–30% after server-side migration.
Server-Side Tagging Impact — B2B SaaS Benchmarks
−38%
Data loss from
ad blockers
400d
Cookie lifetime
(was 7 days ITP)
−0.9s
LCP improvement
on average
−22%
Google Ads CPL
after migration
The 12 events every B2B SaaS
GA4 property needs
Every event is fired via GTM, carries persistent UTM parameters, and feeds both GA4 and the ad platforms via the server container.
| Event Name | Funnel Stage | What It Tracks | Key Parameters | Source |
|---|---|---|---|---|
demo_requested |
Conversion | Demo form submit or HubSpot calendar link click | utm_source, utm_medium, utm_campaign, form_id |
GTM trigger |
demo_completed |
Conversion | Demo call occurred — sent from CRM post-meeting webhook | deal_id, rep_name, original_utm_source |
Measurement Protocol |
trial_started |
Activation | Trial or free plan signup confirmed | plan_type, utm_source, signup_method |
GTM trigger |
trial_activated |
Activation | First meaningful product action (e.g. first project created, first report run) | feature_used, days_since_signup, user_id (hashed) |
App event |
pricing_viewed |
Awareness | Pricing page visit — high intent signal for ad retargeting | page_path, scroll_depth, session_count |
GTM trigger |
payment_initiated |
Revenue | Checkout / billing page reached | plan_name, plan_value, currency |
GTM trigger |
subscription_started |
Revenue | First payment processed — plan activated | plan_name, mrr_value, billing_cycle |
App / Stripe webhook |
closed_won |
Revenue | CRM deal closed-won — full revenue attribution event | deal_value, original_utm_source, utm_campaign, days_to_close |
Measurement Protocol |
integration_connected |
Activation | Key integration enabled — high LTV predictor | integration_name, user_id, days_since_signup |
App event |
team_member_invited |
Activation | Second user invited — multi-seat expansion signal | invitee_role, seat_count, account_age_days |
App event |
upgrade_initiated |
Revenue | Plan upgrade page visited or upgrade CTA clicked | current_plan, target_plan, trigger_page |
GTM trigger |
churn_risk_signal |
Awareness | Cancellation page visited or downgrade initiated | page_path, current_plan, days_since_last_activity |
GTM trigger |
From first ad click
to closed-won —
in GA4
The biggest attribution gap in B2B SaaS: GA4 knows about the demo booking. Your CRM knows about the closed deal. Without the Measurement Protocol bridge, they never talk to each other — and you never know which channel produced which revenue.
We build the bridge. Every closed-won deal in HubSpot or Salesforce sends a closed_won event back into GA4 — with the original UTM parameters, channel, and deal value attached. Your Looker Studio dashboard then shows real CAC per channel, not estimated CPL.
Prospect clicks a Google Ads or LinkedIn ad
UTM parameters captured. GA4 session starts. _ga client ID stored as server-side first-party cookie.
Prospect books a demo
demo_requested fires via GTM. UTM source stored in HubSpot contact property via HubSpot tracking script.
Deal moves through CRM pipeline
30 days pass. HubSpot deal moves: MQL → SQL → Proposal → Closed Won. GA4 is unaware — until now.
Deal marked Closed Won in HubSpot
HubSpot workflow fires a webhook to a Google Cloud Function with deal value, contact ID, and all original UTM properties.
{ "deal_value": 14400, "utm_source": "google", "utm_campaign": "b2b-saas-cac" }
Measurement Protocol sends closed_won to GA4
Cloud Function POSTs to https://www.google-analytics.com/mp/collect with client_id, event name, deal value, and original UTMs. GA4 attributes the revenue to the correct source.
Looker Studio shows real CAC per channel
GA4 now knows: Google Ads campaign X produced 12 closed deals worth $172,800. Channel CAC = $2,400. LTV:CAC = 7.2:1. Budget decision made.
From audit to live attribution
in 4–6 weeks
A structured five-phase delivery. Each phase is documented, reviewed with your growth team, and signed off before the next begins.
Week 1
Audit & Strategy
Review existing GA4 setup, GTM container, CRM pipeline stages, and ad platform conversion tracking. Identify all tracking gaps and define the event taxonomy.
5 business days
Week 1–2
GTM Architecture
Build GTM web container with full B2B SaaS event triggers. Deploy GTM server container on Google Cloud. Configure custom subdomain for first-party tracking.
5–7 business days
Week 2–3
Server-Side Migration
Migrate GA4, Google Ads, LinkedIn, and Meta tags to server container. Test in preview mode. Validate event data in GA4 DebugView and ad platform conversion UIs.
5–7 business days
Week 3–5
CRM Integration
Build HubSpot / Salesforce webhook + Cloud Function pipeline. Implement Measurement Protocol events. Store GA4 client_id on CRM contact. Test closed-won attribution end-to-end.
7–10 business days
Week 5–6
Dashboard & Handover
Build Looker Studio dashboard: blended CAC, LTV:CAC per channel, CAC payback period, funnel conversion rates. Full documentation handover. 30-day support window.
5 business days
The six GA4 mistakes we find
in every B2B SaaS audit
GA4 · Mistake 01
Enhanced measurement doing too much
Enhanced measurement enabled with all options on — creating hundreds of scroll, outbound_click, and video_play events that inflate session counts and pollute reports with noise.
How we fix itDisable enhanced measurement except scroll depth. Custom GTM triggers replace it with controlled, parameter-rich events.
GTM · Mistake 02
All conversions tracking to page_view
Conversion events set up as "page view on /thank-you" — which fires for every session that ever visits the thank-you page, including direct navigation. Result: inflated conversions and CPL data that cannot be trusted.
How we fix itReplace page_view triggers with form submission triggers + GTM dataLayer events fired only on genuine conversion actions.
Server-Side · Mistake 03
No server container — client-side only
Running GA4, Google Ads, LinkedIn, and Meta all as client-side tags — losing 30–40% of conversion data to ad blockers and browser privacy restrictions. Google Ads Smart Bidding training on incomplete data, raising effective CPL.
How we fix itDeploy GTM server container. Migrate all conversion tags to server-side. First-party cookies eliminate browser blocking.
Attribution · Mistake 04
No Measurement Protocol integration
GA4 knows about demo bookings. CRM knows about closed deals. No bridge between them. VP Sales sees $240K in closed revenue. Growth team has no idea which channel, campaign, or ad produced it. CAC calculated from CPL guesses, not closed deals.
How we fix itBuild HubSpot/Salesforce → Cloud Function → Measurement Protocol pipeline. Closed-won events in GA4 within 48 hours.
Data · Mistake 05
UTMs stripped on redirect
Ad UTM parameters are lost when the landing page redirects to a subdomain (e.g., app.saas.com), when HubSpot calendar opens in a new window, or when a payment processor redirects mid-funnel. Attribution reverts to (direct).
How we fix itPersist UTM parameters in a first-party cookie on first touch. Pass them via dataLayer through all redirects and cross-domain handoffs.
Reporting · Mistake 06
Data retention set to 2 months
GA4's default data retention is 2 months. After 2 months, exploration reports return (other) for user-level data. Any cohort analysis, LTV calculation, or multi-touch attribution older than 60 days becomes unreliable without upgrading retention.
How we fix itSet GA4 data retention to 14 months on day one. Connect BigQuery export for unlimited historical raw event storage.
Everything delivered.
Fully documented.
Your team owns it.
We don't just set it up and disappear. Every deliverable comes with technical documentation your growth team can hand to any developer 12 months from now.
Book Free GA4 Audit01
GA4 Property Configuration
Property setup, data streams, Google Signals, BigQuery export, data retention 14 months, conversion events defined and marked.
02
GTM Web Container
Full B2B SaaS event taxonomy implemented — 12 events with parameters, triggers, and dataLayer spec. Version-controlled and documented.
03
GTM Server Container
Deployed on Google Cloud Run at your subdomain. GA4, Google Ads, LinkedIn, and Meta tags migrated server-side. First-party cookie config.
04
Measurement Protocol Pipeline
HubSpot / Salesforce webhook → Cloud Function → GA4 Measurement Protocol. Closed-won events in GA4 with original UTMs and deal value.
05
Looker Studio Dashboard
Live dashboard: blended CAC, LTV:CAC per channel, CAC payback period, funnel conversion rates, channel comparison table.
06
Google Ads Enhanced Conversions
Enhanced Conversions for Web configured via GTM server container. Hashed email matching for improved conversion modelling accuracy.
07
Technical Documentation
DataLayer spec, event dictionary, GTM container export, Cloud Function code, architecture diagram — all in a shared Notion or Google Doc.
08
30-Day Support Window
Slack/email access to our team for 30 days post-launch. We fix any tracking discrepancies, answer developer questions, and review first-month data together.
GA4 questions
answered
More technical questions? Book a free audit and we'll walk through your current setup.
Book Free GA4 AuditWhat is server-side tagging and why does it matter for B2B SaaS? +
Server-side tagging moves your GA4, Google Ads, and LinkedIn tags from the visitor's browser to a server container you control — hosted on Google Cloud at your own subdomain. Browsers and ad blockers can't distinguish first-party requests from third-party tracking, so data loss drops from 35% to under 3%. For B2B SaaS with a tech-savvy ICP who uses Brave, Firefox, or Safari, this is the single highest-impact change you can make to your attribution accuracy.
How does the Measurement Protocol connect GA4 to HubSpot? +
The GA4 Measurement Protocol is an HTTP API that lets you send events to GA4 from any server. When a deal closes in HubSpot, a workflow triggers a webhook to a Google Cloud Function. The function looks up the contact's stored GA4 client_id (saved when they first visited your site), then POSTs a closed_won event to the Measurement Protocol API with the deal value and original UTM parameters. GA4 then attributes that revenue to the correct source — even if the deal closed 60 days after the first visit.
How much does the server container cost to run? +
GTM Server Container runs on Google Cloud Run, which bills based on request volume and compute. For a typical B2B SaaS site with 10,000–50,000 monthly sessions, the cost is $8–$25/month. Google provides a minimum 3-instance allocation for GTM Server ($60–$100/month for always-on instances) but this can be reduced by using 0-to-1 minimum instance scaling for lower-traffic sites. We configure this during setup based on your traffic volume.
Do I need to touch any code on my SaaS app? +
Partially. The GTM web container handles most tracking via JavaScript triggers without code changes. However, for app-level events like trial_activated, integration_connected, and team_member_invited, your engineering team needs to push events to the dataLayer. We provide the exact dataLayer spec and code snippets for each event — typically 1–3 hours of engineering work total. The Cloud Function for the Measurement Protocol is fully self-contained and doesn't require changes to your app.
We use Salesforce, not HubSpot. Does the Measurement Protocol integration still work? +
Yes. The Measurement Protocol pipeline works with any CRM that can send a webhook on deal stage change. For Salesforce we use Process Builder or Flow to trigger an outbound message on Closed Won → Cloud Function → GA4 Measurement Protocol. The main requirement is that the Salesforce contact has the GA4 client_id stored as a contact property — which we configure on first site visit. The same applies to custom CRMs, Pipedrive, or any tool with webhook support.
What's in the Looker Studio dashboard? +
The dashboard has five views: (1) Funnel overview — conversion rate at each stage from session to closed-won; (2) Channel performance — sessions, demos, trials, closed deals, and CAC per channel; (3) Campaign performance — same metrics by campaign; (4) LTV:CAC analysis — deal value per channel vs spend per channel; (5) CAC payback period by cohort. It's connected live to GA4 and refreshes daily. We use a clean, board-ready design that your VP Sales or CMO can read without training.
Find out exactly what
your GA4 is missing
30 minutes. We review your GA4 property, GTM container, and CRM connection. We tell you the three highest-leverage fixes — whether you work with us or not.
Already have GA4 but suspect it's misconfigured? We'll find the gaps and give you a prioritised fix list.