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.
- ✅ If an event’s timestamp equals
user_first_touch_timestamp, the visit is new - 🔁 If an event’s timestamp is after
user_first_touch_timestamp, the visit is returning
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:
- Replace
analytics_XXXXwith your GA4 dataset name - Use different
event_nameif needed (e.g.,'page_view') - Add more filters (device, location, traffic source, etc.)
Example Output
| user_pseudo_id | event_date | user_type |
|---|---|---|
| A123XYZ | 2025-08-01 | New |
| A123XYZ | 2025-08-03 | Returning |
| B456DEF | 2025-08-02 | New |
Why It Matters
Segmenting users like this lets you:
- 🧭 Analyze retention and user lifecycle
- 📈 Compare engagement between new and returning users
- 🎯 Personalize campaigns based on behavior
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!
