Skip to main content

How to extract GA4's event sequencing in BigQuery using the new batch fields

Katie Kaczmarek24 February 20254 min read
How to extract GA4's event sequencing in BigQuery using the new batch fields

Google Analytics 4 (GA4) exports event data to BigQuery, enabling detailed user behavior analysis. However, GA4 batches events before sending them, making GA4 event sequencing in BigQuery more complex. Fortunately, three fields—batch_event_index, batch_ordering_id, and batch_page_id—help provide precise sequencing information.

For a full schema of the GA4 export, head over to google documentation.

This article breaks down these fields in a clear, practical way and shows how to use them together to reconstruct a user's journey in GA4 BigQuery exports.

batch_event_index: The Order of Events Within a Batch

Ever wondered if GA4 sends events in real time? Spoiler alert: it doesn’t! GA4 often groups multiple events together in a batch before sending them to improve efficiency. This means that events can arrive at the same time even if they actually happened in a specific order.

What is batch_event_index?

  • Shows the order of events within a batch, based on when they actually happened on the user’s device.
  • Makes sure that even if events are sent together, we can still analyse them in their true sequence.

Example: Events in a batch

Picture this: A user interacts with a webpage and does the following:

  1. Clicks a button
  2. Scrolls down
  3. Views a product

If GA4 sends these events as a batch, they might appear in BigQuery like this:

event_namebatch_event_index
button_click0
scroll1
view_product2

Even though they were transmitted together, batch_event_index keeps the correct event order intact.

Why this matters

  • Prevents misleading event sequences
  • Helps analyse multi-step interactions correctly
  • Useful for debugging when actions happen close together

batch_ordering_id: How GA4 sends batches

While batch_event_index helps us analyse event order within a batch, batch_ordering_id tells us the order of different batches sent from a page.

Need help with your data platform?

We build intelligence platforms on BigQuery, Dataform and Google Cloud - from setup to ongoing optimisation.

What is batch_ordering_id?

  • A steadily increasing number that increments every time GA4 sends a new batch of events.
  • Helps separate events that were sent in different network requests.

Example: Two separate batches

A user browses a website and interacts with multiple elements. Due to network optimisation, their browser sends two batches of events instead of one.

event_namebatch_ordering_idbatch_event_index
button_click10
scroll11
view_product20
add_to_cart21

What this tells us:

  • The first two events (button_click, scroll) were sent in batch 1.
  • The next two events (view_product, add_to_cart) were sent in batch 2.
  • Within each batch, batch_event_index keeps track of the order.

Why this matters

  • Helps track how events are grouped before being sent
  • Avoids misinterpreting event order due to delayed network requests
  • Useful for debugging and optimising event tracking

batch_page_id: Tracking Events Across Pages

We’ve talked about tracking event order on a single page, but what about users navigating across multiple pages in one session? That’s where batch_page_id comes in.

What is batch_page_id?

  • A sequential number assigned to each page a user visits.
  • Increases each time the user navigates to a new page.
  • Ensures that all events from the same page share the same batch_page_id.

Example: Multi-Page Journey

Let’s say a user moves through a website:

  1. Homepage (batch_page_id = 1)
  2. Product Page (batch_page_id = 2)
  3. Checkout Page (batch_page_id = 3)
event_namebatch_page_id
page_view (home)1
button_click (home)1
page_view (product)2
add_to_cart (product)2
page_view (checkout)3

Why this matters

  • Makes multi-page journey analysis much easier
  • Helps group events by where they happened
  • Avoids confusion when users navigate quickly between pages

How to use these fields together for customer journey analysis

To accurately reconstruct a user’s journey, we need to use all three fields together.

Example Query: Rebuilding a customer journey in BigQuery

SELECT 
  user_pseudo_id, 
  event_name, 
  event_timestamp, 
  batch_page_id, 
  batch_ordering_id, 
  batch_event_index
FROM `project.dataset.events_*`
WHERE _TABLE_SUFFIX = FORMAT_DATE('%Y%m%d', DATE_SUB(CURRENT_DATE(), INTERVAL 1 DAY))
ORDER BY user_pseudo_id, batch_page_id, batch_ordering_id, batch_event_index;

How this works

  • Groups user interactions by page (batch_page_id)
  • Orders batches of events sent together (batch_ordering_id)
  • Preserves the order of events within each batch (batch_event_index)

This lets us accurately rebuild a user’s journey step-by-step, even when GA4 sends events in batches.

Final thoughts

GA4’s batching system improves efficiency, but it also adds complexity. By using batch_event_index, batch_ordering_id, and batch_page_id, we can reconstruct user interactions with confidence. These fields are essential for:

  • Tracking user behaviour across multiple pages
  • Ensuring event order integrity within batches
  • Analysing engagement patterns without guesswork

Using these fields in BigQuery unlocks deeper insights into customer journeys, helping you make better, data-driven decisions.


Have you started using these fields in your GA4 analysis? What challenges have you faced in reconstructing user journeys? Let’s discuss!

Need help with your data platform?

We build intelligence platforms on BigQuery, Dataform and Google Cloud - from setup to ongoing optimisation.

How ready is your data?

Take our short assessment to find out where your data stack stands and what to prioritise next.


Suggested content

BigQuery Tips: When your query is technically correct but BigQuery won't run it

There is a particular kind of frustration that comes from staring at a query you know is correct and watching it fail. No syntax error. No logic problem. Just a wall. We hit two of them on the same project. What we were building The job was to migrate ga4_daily_snapshot for a large enterprise client from a BigQuery scheduled query into a proper Dataform pipeline. The scheduled query had been added to over time until it was too large to maintain with any confidence. Moving it to Dataform w

Katie Kaczmarek17 Aug 2026

BigQuery Tips: The subquery in your WHERE clause that's scanning your entire table

There is a pattern that appears in a lot of BigQuery pipelines and looks completely reasonable. You have a control table that stores the latest processed date. Rather than hardcoding a date into your query, you pull it dynamically: SELECT * FROM `project.dataset.events` WHERE event_date = ( SELECT latest FROM `project.dataset.control_table` ); The query returns the right results. The logic is clean. And if your events table is large and date-partitioned, you might be scanning the entire

Katie Kaczmarek13 Aug 2026

BigQuery Tips: Arrays in BigQuery - what they are and how to get data out of them

If you have ever opened a GA4 export in BigQuery for the first time and found yourself looking at a column called event_params that seemed to contain an entire table inside each row, this post is for you. Arrays are not trying to make your life harder. Once you understand why they exist and what to do with them, they stop being intimidating. Why BigQuery uses arrays GA4 tracks events. Each event can have many parameters. A purchase event might have a transaction ID, a value, a currency an

Katie Kaczmarek10 Aug 2026