Stuifbergen.com<p><strong>GA4 intraday exports and cookieless pings</strong></p><p>I build a lot of reports for clients that use Big Query GA4 as source.</p><p>Now.. that works like a charm. But.. you will need to wait some time to get processed data from the <code>events_</code> tables.</p><p>More recent data will appear in the streaming <code>_intraday_</code> tables, if you have that enabled. But.. that data is not always complete! Especially when your site has <em>consent mode</em> enabled, and does not set a cookie until after consent.</p><p>Here’s how it works:</p><p><strong>The scenario</strong></p><p>Someone visits the site for the first time (source: some campaign), gets confronted with the cookie banner, and then clicks accept.</p><p>We tagged the site correctly, so this is what happens</p><ol><li>a <code>page_view</code> event triggers (with URL parameters) – and notices analytics consent is denied (the default)</li><li>the tracker attaches some parameters to this hit, to help processing<ul><li>a session is started</li><li>this is the first visit</li></ul></li><li>there is an item list on the page: <code>view_item_list</code> event is triggered</li><li>the cookiebanner pops up (event: <code>cookiebar_view</code>)</li><li>the visitor clicks accept (event: <code>cookiebar_accept</code>) and the tracker gets sent a <code>granted</code> signal</li><li>now the cookie can be uses, and is attached to an automatic event <code>user_engagement</code></li></ol><p>Sounds simple. Now, let’s see what is streamed into Big Query:</p><p><strong>The streaming data gap</strong></p><p>Basically, the intraday tables store what happens, as it happens.</p><ul><li>cookie field ( <code>user_pseudo_id</code> ) is filled in on hits on/after consent</li><li>cookie field is <code>NULL</code> for hits before consent</li></ul><p>As it should be, right? But there’s a third bullet:</p><ul><li>first batch of events will not appear in the <code>intraday</code> table!</li></ul><p>Here’s what we see (most recent hit first, read from bottom to top)</p><ol><li>the page_view is missing in the streaming table</li><li>the <code>collected_traffic_source</code> information is missing (it is always only filled in on the first batch of events)</li><li>As a byproduct, we also do not see the session start and first visit</li><li>the other events are all sent without a cookie</li><li>after consent, we see the <code>user_pseudo_id</code> – finally</li></ol><p>The next day.. Google has glued it all together</p><p><strong>Processed data: every event has a row</strong></p><p>The following is in the processed data: (most recent hit first, read from bottom to top)</p><ul><li>The page_view event and all other events leading up to the consent have a cookie attached to it! Google rescued that information</li><li>the “Attached” parameters to the hit expand to two extra rows<ul><li>session_start</li><li>first_visit</li></ul></li><li>we have source information: <code>collected_traffic_source</code> is present – on the first batch, as normal</li></ul><p>Not visible in the screenshot: <code>session_traffic_source_last_click</code> – the session information is properly filled in.</p><p><strong>The consequences</strong></p><p>If you decide to use <code>intraday</code> tables in your Big Query reports: be aware that although the information is fresh (no pun intended, GA360 users), it’s incomplete</p><ul><li>intraday misses crucial events, namely the first batch (most often a page_view)<ul><li>bye bye landing_page reports based on page_views</li><li>bye bye traffic source reports based on session_traffic_source_last_click or collected_traffic_source</li></ul></li><li>intraday misses cookies on some events<ul><li>which is not too much of an issue, really</li></ul></li></ul><p><strong>Your experiences?</strong></p><p>Do you use intraday tables in your models? Have you found clever workarounds to get the correct data in?</p><p>Let me know! Drop a comment here, or send me a <a href="https://bsky.app/profile/zjuul.net" rel="nofollow noopener" target="_blank">bluesky</a> message!</p><p><strong>Still here?</strong></p><p>Check out GA4Dataform – a product I’ve helped build that <a href="https://ga4dataform.com/" rel="nofollow noopener" target="_blank">turns the GA4 Big Query exports into usable tables</a>!</p><p></p> <p></p><p><strong>Related posts:</strong></p> <a class="" rel="nofollow noopener" href="https://stuifbergen.com/2021/09/google-analytics-4-truncates-page-location/" target="_blank"><span class="">Google Analytics 4 truncates page location</span></a><a class="" rel="nofollow noopener" href="https://stuifbergen.com/2022/01/making-sense-of-event-parameters-in-ga4/" target="_blank"><span class="">Making sense of Event Parameters in GA4</span></a><a class="" rel="nofollow noopener" href="https://stuifbergen.com/2022/06/powertips-for-ga4-implementations/" target="_blank"><span class="">Make your GA4 life easier: Some powertips!</span></a><a class="" rel="nofollow noopener" href="https://stuifbergen.com/2024/04/smart-incremental-ga4-tables-in-dataform/" target="_blank"><span class="">Smart incremental GA4 tables in Dataform</span></a> <p><a rel="nofollow noopener" class="hashtag u-tag u-category" href="https://stuifbergen.com/tag/big-query/" target="_blank">#bigQuery</a> <a rel="nofollow noopener" class="hashtag u-tag u-category" href="https://stuifbergen.com/tag/consent-mode/" target="_blank">#consentMode</a> <a rel="nofollow noopener" class="hashtag u-tag u-category" href="https://stuifbergen.com/tag/cookies/" target="_blank">#cookies</a> <a rel="nofollow noopener" class="hashtag u-tag u-category" href="https://stuifbergen.com/tag/ga4/" target="_blank">#ga4</a> <a rel="nofollow noopener" class="hashtag u-tag u-category" href="https://stuifbergen.com/tag/tagging/" target="_blank">#tagging</a></p>