Unlock the power of Google Analytics with Big Query

How to Track New vs. Returning Users in GA4 Using BigQuery

Understanding the difference between new and returning users is critical for marketers and analysts who care about user acquisition, retention, and behavior trends. While GA4 simplifies many things, it doesn’t directly provide an easy way to segment returning users—especially if you want to go beyond default reports.

This deep dive walks you through how GA4 defines users, why the BigQuery export matters, and how to write SQL queries to classify user types accurately using real-world examples.


What Does GA4 Consider a New vs. Returning User?

Let’s start with Google’s own definition:

“A new user is someone who interacts with your site or app for the first time (measured by the absence of a prior user_first_touch_timestamp).”
Google GA4 Glossary – User definitions

GA4 creates a unique identifier called user_pseudo_id and tracks the user’s first touch timestamp. This is stored as user_first_touch_timestamp.

GA4 doesn’t track “returning users” in the UI by default, but the data is all there in BigQuery.


Scenario 1: First-Time Visitor

Let’s say a user visits your site for the first time on August 1, 2025, and views a product page.

In BigQuery, that event row might look like:

user_pseudo_id: A123XYZ  
event_timestamp: 1690915200000  
user_first_touch_timestamp: 1690915200000

Since event_timestamp = user_first_touch_timestamp, this is clearly a new user.


Scenario 2: Returning Visitor

Now, suppose the same user comes back on August 3, 2025, and starts another session.

user_pseudo_id: A123XYZ  
event_timestamp: 1691088000000  
user_first_touch_timestamp: 1690915200000

This time, event_timestamp > user_first_touch_timestamp, which means the user is returning.


SQL Query to Identify New vs. Returning Users

Let’s write a simple BigQuery SQL query to classify user visits.

WITH base_events AS (
  SELECT
    user_pseudo_id,
    user_first_touch_timestamp,
    event_timestamp,
    DATE(TIMESTAMP_MICROS(event_timestamp)) AS event_date
  FROM
    `your_project_id.analytics_XXXX.events_*`
  WHERE
    _TABLE_SUFFIX BETWEEN '20250801' AND '20250804'
    AND event_name = 'session_start'
)

SELECT
  user_pseudo_id,
  event_date,
  CASE
    WHEN event_timestamp = user_first_touch_timestamp THEN 'New'
    ELSE 'Returning'
  END AS user_type
FROM base_events

Customize:


Example Output

user_pseudo_idevent_dateuser_type
A123XYZ2025-08-01New
A123XYZ2025-08-03Returning
B456DEF2025-08-02New

Why It Matters

Segmenting users like this lets you:

Example: If returning users bounce more, you may need to improve your homepage experience. If new users convert better, your acquisition campaigns are solid.


Bonus: Count of Users by Type Per Day

SELECT
  event_date,
  COUNT(DISTINCT user_pseudo_id) AS total_users,
  COUNT(DISTINCT IF(event_timestamp = user_first_touch_timestamp, user_pseudo_id, NULL)) AS new_users,
  COUNT(DISTINCT IF(event_timestamp != user_first_touch_timestamp, user_pseudo_id, NULL)) AS returning_users
FROM base_events
GROUP BY event_date
ORDER BY event_date

Final Thoughts

GA4 hides a lot of power under the hood, but BigQuery unlocks it. With just a few lines of SQL, you can segment your audience far beyond what’s visible in the GA4 interface.

Whether you’re a marketer looking at retention, a product analyst tracking user lifecycle, or a data team building dashboards—knowing the new vs. returning split is a must.


📘 Want more tutorials like this?
Subscribe or follow for weekly Deep Dive Tutorials on GA4 + BigQuery!

Discover more from GA4 BigQuery

Subscribe now to keep reading and get access to the full archive.

Continue reading