Unlock the power of Google Analytics with Big Query

Marketing Channel Performance in GA4: Tracking New vs. Returning Users

Understanding how different channels contribute to user acquisition vs. user retention is critical for optimizing spend and strategy. In GA4, while you get some visibility into user types, a more detailed analysis often requires BigQuery SQL.

This guide walks you through:

  1. Why this analysis matters
  2. How GA4 tracks user types
  3. Step-by-step: Build a New vs. Returning User breakdown by marketing channel using BigQuery
  4. Key insights to act on

Why This Analysis Matters

Most marketing teams ask:

By breaking down New vs. Returning Users by Channel, you can double down on channels that drive loyalty, not just top-funnel awareness.


How GA4 Tracks New and Returning Users

ConceptExplanation
New UserDetermined by GA4 using the user_first_touch_timestamp. If it’s the user’s first event, they are marked as “new.”
Returning UserAny session after the first one. Not tracked by default in GA4 reports, but can be derived using SQL.
ChannelsTracked via session_source, session_medium, session_campaign, etc. in GA4 export.

GA4 Documentation: Measure New and Returning Users


How to Do It in BigQuery

Step 1: Start with GA4 BigQuery Export

We’ll use the events_YYYYMMDD table that includes all session data and event-level parameters.

WITH base AS (
  SELECT
    user_pseudo_id,
    MIN(event_timestamp) AS first_seen,
    user_first_touch_timestamp,
    session_source,
    session_medium,
    session_campaign,
    event_date
  FROM
    `your_project.analytics_XXXX.events_*`
  WHERE
    _TABLE_SUFFIX BETWEEN '20250801' AND '20250806'
    AND event_name = 'session_start'
  GROUP BY
    user_pseudo_id,
    user_first_touch_timestamp,
    session_source,
    session_medium,
    session_campaign,
    event_date
),

classified AS (
  SELECT
    *,
    CASE
      WHEN event_timestamp = user_first_touch_timestamp THEN 'New'
      WHEN event_timestamp > user_first_touch_timestamp THEN 'Returning'
      ELSE 'Unknown'
    END AS user_type
  FROM base
)

SELECT
  session_source,
  session_medium,
  user_type,
  COUNT(DISTINCT user_pseudo_id) AS users
FROM classified
GROUP BY 1, 2, 3
ORDER BY users DESC;

Example Output

Channel SourceMediumUser TypeUsers
googlecpcNew2,340
googlecpcReturning980
emailemailNew320
emailemailReturning1,150

Interpretation:


Key Considerations


Tips for Marketers

Discover more from GA4 BigQuery

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

Continue reading