Build a GA4 Roll-up Property Using Server-side Google Tag Manager

One or multiple properties?

One property for all means a lot of filter work in GA4 reports or different reporting UIs via library / menu customization for different parts and tasks. This does not solve the problem that several time zones are then lumped together on international websites, but that does not count as a counter argument here, because it would have been the case in UA. If you have already operated a parallel UA property there, this would theoretically also be possible with GA4.

Client-only dual tagging option for Universal Analytics
Stream Consolidation for Universal Analytics
Stream consolidation for GA4 with ssGTM: Possible?
  • Session ID: It changes with the property when navigating from one part of the website to another. For example, if you switch between blog and shop with separate properties for measurement.
  • Session number: The number is also not consistent if you throw all GA4 hits into one pool. The above switching from blog to shop creates a new session from the point of view of the shop property with an (usually) different number, because one usually does not always visit all parts of a website
  • Session Start and First Visit marker: Whenever a session arises, a marker is sent with the hit (_ss=1) which causes a session_start event to arise in GA4. Also (if the session number is 1 there is a marker for the first visit (_fv=1) which results in a first_visit event and ensures that there is something like a “First User Source” etc. in GA4
  • If the renewed visit to the www property begins, a session and a start arise. The session ID is unique and the visit number is 3 because there have been previous visits to the property. Further events can now follow within the property
  • One click leads to the blog (where no visit has taken place so far). A new session is created there from the perspective of the blog property and a session_start and first_visit are reported — also to the roll-up property. From their point of view, the session ID and number have also changed
  • The same thing happens when you switch to the shop, but there is no first_visit because there was already a visit there from a previous session
  • From the shop back to www, the session ID and number now changes again from the point of view of the roll-up property. Since a www session already exists, there are no new session_start events
How a roll-up property “sees” consolidted streams
  1. Sending all hits using a standard tag for GA4 with overridden measurement id to consolidate all hits in one roll-up property. Suitable for mainly separate hosts or domains
  2. Like 1), but with special handling of changes between the properties and new sessions that arise as a result. For useful results, a separate, comprehensive session should also be managed. This can optionally be controlled in a client-side GTM or from server-side
  3. Using the GA4 Measurement Protocol
  4. A separate client in ssGTM that sends all hits to the roll-up property (adjusted for further session starts and its own session control as with option 2) and then passes it on to the normal tags
  5. Duplication of hits in the client by monkey patching the send function in the browser. This option is not dealt with here and the result is comparable to option 1. It is only mentioned here for the sake of completeness.

Option 1: Standard GA4 tag to consolidate all hits into one property

A simple tag that fires on all GA4 hits regardless of the Measurement ID and overwrites it with the new ID of the collection property can only be used with the above restrictions. Even overriding individual fields is of no help here if it is the specific field in question. Because the information about the session start or first visit when changing data streams sits in “System Properties” under the key x-ga-system_properties in the event model, and overwriting doesn’t seem to change anything in the outgoing hit. I tried it first by removing the parameters from the original content of the information stored as an object in a variable using a custom template. However, this does not work, because an _ss=1 and eventually _fv=1 is still sent out when you look at the outgoing hits. Removing the information by overwriting it with an “Undefined Value” variable has the same effect; ditto the editing functions for parameters that the tag brings with it. This method is therefore not very suitable because it can lead to an overflow of sessions.

Independent roll-up session for consistent session data
Set your own “session start already measured” marker with a cookie
Blocking trigger for session_start events when property changes
Reading the session start marker from incoming events
Quick but working roll-up session handling in client-side GTM
Access roll-up session data in ssGTM
Override session data in “roll-up” GA4 tag
Filling the gaps with GA4 Measurement Protocol
Trigger for firing GA4MP tag (and blocking regular roll-up tag)
(Too) simple Measurement Protocol hit with HTTP Request tag in ssGTM
  • Users and sessions should be lower, as there is a high probability of switching between the individual parts
  • Pageviews should match
  • Revenue and transactions should also be the same
  • Total conversions should correspond to the roll-up value
  • Event count should be lower because First Visit and Session Start events are missing
  • The distribution of users to individual source / medium combination is independent of the individual properties (not shown in the picture)
Results for roll-up property compared to single properies
Event breakdown for “missing” events
Not just page views: every event can contain a session start marker
  • There may be inconsistencies in the configuration of event properties… and — much worse — user properties. Once there is a session scope, it doesn’t get any better.
  • Within a session, the status of an “Engaged” session can change back to “Not Engaged” when the property is changed
  • result quality of the roll-up property is largely dependent on the setup of the individual properties. All partial properties should ideally be set up in a consistent way and kept in sync
  • Missing first visit information such as “First Session Source” occur when legacy issues exist, i.e. client IDs are not new. The first entry measured in this way may not be reported as a first visit from the roll-up perspective. In that case, a marker for the first visit is then simply missing for this new user and the corresponding dimensions are therefore also not assigned.
  • The limit is reached with cross domain tracking (except for option 1), because your own session cannot be transported between the domains (without further work in the client and sacrificing httpOnly … or switching to fingerprints and server-side state).



Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store