GA4 without gtag.js
Deliver events to GA4 via Measurement Protocol with a self-generated client_id, server-set _ga cookie, and ITP-exempt 400-day expiry. Full GA4 reporting with zero Google JavaScript in the browser.
The problem with gtag.js
Google's client-side tracking has four fundamental problems that cannot be fixed with configuration changes. They are architectural limitations.
80KB+ Payload
gtag.js loads 80KB+ of JavaScript before a single event fires. Combined with GTM, total payload regularly exceeds 200KB — directly impacting Core Web Vitals and conversion rates.
ITP-Limited Cookies
Safari's Intelligent Tracking Prevention caps client-side JavaScript cookies at 7 days. Your _ga cookie expires weekly, fragmenting user sessions and inflating visitor counts.
Ad Blocker Blocked
EasyList blocks google-analytics.com and googletagmanager.com by default. 30-40% of technical audiences never register a single event. Your data has a permanent blind spot.
Consent Race Conditions
Client-side consent banners race against tag execution. gtag.js may fire before consent is granted, or consent may be revoked after events are already in flight.
How server-side GA4 works
Six steps from browser event to GA4 report. No Google JavaScript involved.
Datafly.js collects events
The 4.2KB collector captures page, track, and identify events via sendBeacon. No gtag.js, no Google Tag Manager, no 80KB+ payload.
Server generates client_id
The Ingestion Gateway generates a GA4-format client_id as {random_uint32}.{unix_timestamp} — the exact same format Google uses.
Server sets _ga cookie
The _ga cookie is set via Set-Cookie header with a 400-day expiry. Because it is server-set on your first-party subdomain, it is fully exempt from Safari ITP restrictions.
Pipeline Engine transforms to Measurement Protocol
Your YAML pipeline config maps event properties to GA4 Measurement Protocol parameters. Session data, user properties, and engagement metrics are enriched automatically.
Delivery Worker POSTs to GA4
A purpose-built delivery worker sends the formatted payload to google-analytics.com/mp/collect with your Measurement Protocol API secret. Exponential backoff retry on failure.
GA4 reports populate normally
Events appear in your GA4 property exactly as if they came from gtag.js. Real-time reports, explorations, BigQuery export — everything works as expected.
Transformation configs you can read
Every GA4 event mapping is defined in version-controlled YAML. Review in pull requests, roll back with a commit revert.
# ga4-pageview.yaml — Page view to Measurement Protocol
name: ga4_pageview
integration: google-analytics-4
trigger:
event: page
conditions:
- field: context.page.url
operator: exists
transform:
mapping:
- source: properties.title
target: page_title
- source: context.page.url
target: page_location
- source: context.page.referrer
target: page_referrer
- source: context.locale
target: language
enrichments:
- type: session
fields: [session_id, session_number]
- type: vendor_id
vendor: ga4
cookie: _ga
output:
format: ga4_measurement_protocol
event_name: page_view
endpoint: https://www.google-analytics.com/mp/collect
validate: true# ga4-purchase.yaml — E-commerce purchase event
name: ga4_purchase
integration: google-analytics-4
trigger:
event: track
conditions:
- field: event
operator: equals
value: Order Completed
transform:
mapping:
- source: properties.order_id
target: transaction_id
- source: properties.revenue
target: value
- source: properties.currency
target: currency
default: USD
- source: properties.products
target: items
transform: array_map
fields:
- source: product_id
target: item_id
- source: name
target: item_name
- source: price
target: price
- source: quantity
target: quantity
- source: category
target: item_category
enrichments:
- type: session
fields: [session_id, session_number, engagement_time_msec]
- type: vendor_id
vendor: ga4
cookie: _ga
output:
format: ga4_measurement_protocol
event_name: purchase
endpoint: https://www.google-analytics.com/mp/collect
validate: trueFull GA4 feature support
Everything you use in GA4 today works with server-side delivery. No compromises, no missing features, no manual workarounds.
- Page views
- Custom events
- Session tracking
- Engagement time
- Scroll tracking
- E-commerce: view_item
- E-commerce: add_to_cart
- E-commerce: begin_checkout
- E-commerce: purchase
- User properties
- Cross-domain measurement
- Debug mode validation
- BigQuery export compatibility
- Enhanced measurement events
- Consent mode integration
BigQuery Export Compatibility
Events delivered via Measurement Protocol appear in your BigQuery export with the same schema as client-side events. Your existing queries, dashboards, and ML pipelines continue to work without modification.
See server-side GA4 in action
Book a technical walkthrough where we show you GA4 events flowing from Datafly.js through the pipeline to your GA4 property in real-time. No gtag.js required.