One of the biggest shifts from Universal Analytics to GA4 is the way data is structured around events and scopes. Whether you’re analyzing campaigns, funnels, or user behavior, understanding the difference between event-scoped, session-scoped, and user-scoped metrics is critical.
In this post, we’ll use BigQuery SQL to show how scope affects your numbers — with a practical ecommerce funnel example.
Official documentation: Scopes in GA4
1. Event Scope: Counting at the Granular Level
Event scope means every row in BigQuery represents a single event (like view_item, add_to_cart, or purchase).
SQL Example: Count total product views (event-scoped)
SELECT
COUNT(*) AS total_product_views
FROM
`your_dataset.analytics_XXXX.events_*`
WHERE
event_name = 'view_item'
AND _TABLE_SUFFIX BETWEEN '20250801' AND '20250815'
How this SQL works:
COUNT(*)counts everyview_itemevent.- Each time a user views a product, it’s a new row, so repeat views by the same user are included.
- Best for raw activity counts.
2. Session Scope: Rolling Events into Sessions
Sometimes you want to know how many sessions included an action, not how many times it happened.
SQL Example: Count sessions where at least one add-to-cart occurred
SELECT
COUNT(DISTINCT CONCAT(user_pseudo_id, CAST(event_bundle_sequence_id AS STRING))) AS sessions_with_cart
FROM
`your_dataset.analytics_XXXX.events_*`
WHERE
event_name = 'add_to_cart'
AND _TABLE_SUFFIX BETWEEN '20250801' AND '20250815'
How this SQL works:
- GA4 exports don’t include a direct session ID.
- We approximate sessions by combining
user_pseudo_id+event_bundle_sequence_id. COUNT(DISTINCT …)ensures we only count one cart event per session.- Best for funnel analysis when you care about session-level engagement.
3. User Scope: Unique People Behind Events
Finally, you may want to know how many unique users performed an action.
SQL Example: Count unique users who purchased
SELECT
COUNT(DISTINCT user_pseudo_id) AS users_purchased
FROM
`your_dataset.analytics_XXXX.events_*`
WHERE
event_name = 'purchase'
AND _TABLE_SUFFIX BETWEEN '20250801' AND '20250815'
How this SQL works:
user_pseudo_idrepresents an anonymous GA4 user identifier.- Each user is only counted once, even if they purchased multiple times.
- Best for audience building or estimating reach.
4. Checkout Funnel Example: How Scope Changes the Numbers
Let’s say we want to analyze a 3-step funnel: view → cart → purchase.
Event Scope Query (all raw actions):
SELECT
event_name,
COUNT(*) AS event_count
FROM
`your_dataset.analytics_XXXX.events_*`
WHERE
event_name IN ('view_item', 'add_to_cart', 'purchase')
AND _TABLE_SUFFIX BETWEEN '20250801' AND '20250815'
GROUP BY
event_name
Session Scope Query (sessions with the action):
SELECT
event_name,
COUNT(DISTINCT CONCAT(user_pseudo_id, CAST(event_bundle_sequence_id AS STRING))) AS session_count
FROM
`your_dataset.analytics_XXXX.events_*`
WHERE
event_name IN ('view_item', 'add_to_cart', 'purchase')
AND _TABLE_SUFFIX BETWEEN '20250801' AND '20250815'
GROUP BY
event_name
User Scope Query (unique users per step):
SELECT
event_name,
COUNT(DISTINCT user_pseudo_id) AS users_count
FROM
`your_dataset.analytics_XXXX.events_*`
WHERE
event_name IN ('view_item', 'add_to_cart', 'purchase')
AND _TABLE_SUFFIX BETWEEN '20250801' AND '20250815'
GROUP BY
event_name
Why the numbers differ:
- Event scope will show the highest counts (every click counted).
- Session scope will shrink numbers (multiple events collapse into one per session).
- User scope is often the smallest (a user only counted once even across multiple sessions).
Conclusion
Understanding scope in GA4 BigQuery is key to avoiding misinterpretation. If your funnel drop-offs look huge, check whether you’re analyzing at the event, session, or user level.
When in doubt, ask yourself:
- Do I care about every action? → Event scope.
- Do I care about sessions with that action? → Session scope.
- Do I care about unique users? → User scope.
For further reference, check the official GA4 Scopes documentation.

