6 min read

How to Visualize Session Duration in Google Analytics 4

Session duration tells you how long users actually spend on your site, but GA4 doesn't surface it the same way Universal Analytics did. You'll need to either pull it from Reports with the right dimensions, query the Data API, or analyze raw event data in BigQuery. Here's how.

View Session Metrics in the Google Analytics 4 Reports UI

The fastest way to see session duration is through GA4's built-in reports.

Open the Engagement report and look for session insights

Log into your Google Analytics 4 property and go to Reports > Engagement. GA4 shows you Sessions and Average session duration by default. The Average session duration card displays the mean duration across all sessions for the selected date range.

Create a custom report to segment session duration by dimension

Click Create custom report in the Reports UI. Add Sessions as a metric, then add a dimension like Default channel grouping or Device category to see how session duration varies by source or device type. This breaks down which traffic sources keep users engaged longest.

javascript
// In GA4 UI: Reports > Engagement > Create custom report
// Configure:
// Dimensions: Default channel grouping, Country, Device category
// Metrics: Sessions, Engagement rate
// GA4 automatically calculates average session duration per dimension group
Custom reports calculate session metrics without code

Use segments to filter sessions by duration

Click the Segments button and create a segment for users whose sessions lasted longer than a threshold (e.g., > 3 minutes). Apply this segment to your report to see which users are most engaged.

Tip: GA4 calculates average session duration in seconds. A session with zero duration means the user triggered no engagement events (bounced immediately). These are included in the average, which can make the metric appear lower than expected.

Query Session Metrics with the Google Analytics Data API

For programmatic access or automation, use the Data API to fetch session duration metrics.

Install the Google Analytics Data client library

Add the @google-analytics/data library to your project via npm. This library handles authentication and API requests to GA4's Data API.

Authenticate and call runReport

Create a service account in Google Cloud Console and use its JSON key to authenticate. Call the runReport method to query userEngagementDuration (measured in seconds) grouped by date or dimension.

javascript
const {BetaAnalyticsDataClient} = require('@google-analytics/data');

const client = new BetaAnalyticsDataClient({
  projectId: 'YOUR_GCP_PROJECT_ID',
});

async function visualizeSessionDuration() {
  const request = {
    property: `properties/YOUR_GA4_PROPERTY_ID`,
    dateRanges: [
      {
        startDate: '2024-01-01',
        endDate: '2024-01-31',
      },
    ],
    metrics: [
      { name: 'sessions' },
      { name: 'userEngagementDuration' },
    ],
    dimensions: [
      { name: 'date' },
      { name: 'defaultChannelGroup' },
    ],
  };

  const response = await client.runReport(request);
  
  response[0].rows.forEach((row) => {
    const date = row.dimensionValues[0].value;
    const channel = row.dimensionValues[1].value;
    const sessions = row.metricValues[0].value;
    const engagementSeconds = row.metricValues[1].value;
    const avgDuration = (engagementSeconds / sessions).toFixed(2);
    
    console.log(`${date} - ${channel}: ${sessions} sessions, ${avgDuration}s avg`);
  });
}

visualizeSessionDuration();
Query engagement metrics by date and channel

Calculate average session duration from the response

The API returns userEngagementDuration as a total, not an average. Divide by session count to get the average duration per session. This is the only way to get session duration from the Data API—there's no dedicated "session duration" metric like there was in Universal Analytics.

Watch out: The Data API returns userEngagementDuration in seconds, not milliseconds. This is the total engaged time across all sessions in your query, so you must divide by session count to get the average. Bounced sessions (zero duration) are not included in this metric, so it tends to be higher than the average shown in Reports.

Analyze Session-Level Duration in BigQuery

For deep analysis, export GA4 data to BigQuery and query the raw events table.

Enable BigQuery export in GA4 property settings

Go to Admin > Data collection and modification > Google Cloud Platform and link your BigQuery project. GA4 exports raw events to a dataset called analytics_{PROPERTY_ID}.

Query the events table to calculate session duration

Write a SQL query that groups events by session_id and calculates the time between the first and last event. Use the event_timestamp field (in microseconds) to compute duration.

javascript
SELECT
  user_pseudo_id,
  (SELECT value.int_value FROM UNNEST(event_params) WHERE key='ga_session_id') as session_id,
  COUNT(*) as event_count,
  TIMESTAMP_MICROS(MIN(event_timestamp)) as session_start,
  TIMESTAMP_MICROS(MAX(event_timestamp)) as session_end,
  ROUND((MAX(event_timestamp) - MIN(event_timestamp)) / 1000000, 2) as session_duration_seconds
FROM
  `YOUR_PROJECT.analytics_YOUR_GA4_PROPERTY_ID.events_*`
WHERE
  _TABLE_SUFFIX BETWEEN FORMAT_DATE('%Y%m%d', DATE_SUB(CURRENT_DATE(), INTERVAL 30 DAY))
  AND FORMAT_DATE('%Y%m%d', CURRENT_DATE())
GROUP BY
  user_pseudo_id,
  session_id
ORDER BY
  session_start DESC
LIMIT 1000;
Calculate session duration from raw event timestamps in microseconds

Aggregate by traffic source or user property to find patterns

Add GROUP BY on dimensions like traffic_source or device.category to see which segments have the longest sessions. Join the user_properties table if you need to segment by custom user attributes.

Tip: GA4 events are streamed to BigQuery with a 2–3 hour delay. For real-time analysis, use the Data API instead. Also note that session IDs reset at midnight in each user's timezone, so a session spanning midnight will appear as two separate sessions in the raw data.

Common Pitfalls

  • Confusing userEngagementDuration (the Data API metric) with raw event timestamp differences. They calculate duration differently—the metric excludes bounced sessions, while raw events include them.
  • Forgetting that GA4 counts zero-duration sessions (immediate bounces) in Reports, which lowers your average. The Data API excludes them, so Data API averages always look higher.
  • Using UTC timestamps from BigQuery without converting to the user's timezone. Sessions in GA4 are defined by user timezone, so raw event timestamps may not align visually with session boundaries in Reports.
  • Querying only the most recent day in BigQuery (events_20240101) instead of using wildcard tables (events_*). Single-day queries miss data—use _TABLE_SUFFIX filters to scan the full date range.

Wrapping Up

Session duration in GA4 is accessible three ways: through the Reports UI for quick summaries, the Data API for automated reporting, and BigQuery for granular analysis. Pick the method that fits your workflow—Reports are fastest, the API is most flexible, and BigQuery is best for custom aggregations. If you want to track session behavior automatically across all your tools and connect it to product metrics, Product Analyst can help.

Track these metrics automatically

Product Analyst connects to your stack and surfaces the insights that matter.

Try Product Analyst — Free