In BigQuery, you must be aware of the following caveats when tracking GA4 sessions.

#1 In GA4, a session can start with a ‘session_start’ event or ‘user_engagement’ event.
Both the ‘session_start’ event and the ‘user_engagement’ event contain the ‘ga_session_id’ event parameter.
So
If you calculate sessions by counting each unique combination of ‘user_pseudo_id’ and ‘event_timestamp’ (where ‘event_name’=’session_start’), you will discount all those sessions which did not start with the ‘session_start’ event.
Similarly,
If you calculate sessions by counting each unique combination of ‘user_pseudo_id’ and ‘event_timestamp’ (where ‘event_name’=’user_engagement’), you will discount all those sessions which started with the ‘session_start’ event.
#2 Multiple sessions from different users can have the same ‘ga_session_id’.
Since the ‘ga_session_id’ event parameter is the timestamp of when a GA4 session begins, it is possible that multiple sessions from different users all start at the exact same time, esp. for high-traffic websites.
In such a situation, multiple sessions from different users can have the same ‘ga_session_id’.
So,
If you calculate sessions by counting the unique values of ‘ga_session_id’, you will underreport on sessions, as multiple users can have the same ‘ga_session_id’.
#3 Any GA4 event can potentially start a new session if no active session exists.
In many cases, a session can still be inferred to have started without explicitly seeing either the ‘session_start’ event or the ‘user_engagement’ event in the BigQuery event data.
Whenever GA4 encounters an event without a previous session, it can consider it as a part of a new session.
That means if GA4 detects an event and no existing session is active (based on ‘ga_session_id’ or user session logic), it can create a new session regardless of the event type.
In other words, any GA4 event can potentially start a new session if no active session exists.
For example:
#1 If the first event of a user’s visit is a custom event (like a click or custom engagement event) or ecommerce event (like ‘purchase’), and neither ‘session_start’ nor ‘user_engagement’ has fired, GA4 can infer the start of a session from this first event. This behaviour is common with server-side tracking or Measurement Protocol implementations.
#2 A session can start with ‘page_view’ event due to delayed or missing ‘session_start’ event. In this case, GA4 assumes the session started with the ‘page_view’.
#3 A session can start with a ‘page_view’ event due to users leaving your website before the 10-second user engagement threshold.
#4 A session can start without ‘session_start’ event or the ‘user_engagement’ event if server-side events are sent via Measurement Protocol.
#4 When the Measurement Protocol is used, GA4 tracks only what it is explicitly told to track.
If the Measurement Protocol request does not include a ‘session_start’ event, GA4 will infer the session from the first event.
Since the Measurement Protocol does not automatically generate ‘user_engagement’, this event will also be absent.
Whatever the first event is will mark the start of the session.
#5 A session can start without the ‘session_start’ event or the ‘user_engagement’ event.
A session can start without ‘session_start’ event or the ‘user_engagement’ event if ‘ga_session_id’ is missing from the Measurement Protocol payload.
This is a common misconfiguration when using server-side tracking or custom event tracking via the Measurement Protocol.
#6 Server-side tracking could fail to maintain session continuity, creating a new session for each hit.
If server-side tracking does not maintain the same ga_session_id for multiple hits (like purchase, add_to_cart, etc.), GA4 will assume each event belongs to a new session.
Therefore the most accurate method to calculate GA4 sessions’ in Bigquery is to count each unique combination of ‘user_pseudo_id’ and ‘ga_session_id’.
This method accounts for all sessions, regardless of whether they start with ‘session_start’ and/or ‘user_engagement’ events.
I teach you the logic behind calculating sessions, engaged sessions and other metrics in my GA4 BigQuery course, where you can learn to automate SQL generation via text prompts in ChatGPT.

Related Articles:
- Google Analytics 4 Landing Page Report in BigQuery.
- Google Analytics 4 Exit Page Report in BigQuery.
- Google Analytics 4 Landing Page Dimension in BigQuery.
- GA4 (not set) Landing Pages Show 0 Entrances in BigQuery.
- Google Analytics 4 Page Title, Page Path & Views in BigQuery
- Google Analytics 4 Unique Pageviews in BigQuery.
- Google Analytics 4 Traffic Attribution in BigQuery.
- Finding Real Google Analytics 4 Conversion Paths in BigQuery.
- Tracking Google Analytics 4 UTM Parameters in BigQuery.
- Tracking Google Analytics 4 AI Traffic in BigQuery.
- Tracking peak time for Website Traffic in GA4 BigQuery.
- How to Correctly Work With Google Analytics Data Types in BigQuery.
- Three SQL Query Logic You Must Use For GA4 in BigQuery.
- Four Rules for Google Analytics Data Aggregation in BigQuery.
- Top 10 Optimization Strategies for GA4 SQL in BigQuery.
- How To Correctly Track GA4 Sessions in BigQuery.
- Tracking Google Analytics 4 Engaged Sessions in BigQuery.
- Tracking Google Analytics 4 Total Users in BigQuery.
- Tracking Google Analytics 4 New Users in BigQuery.
- Tracking Google Analytics 4 Returning Users in BigQuery.