6 min read

How to Track Bounce Rate in Google Analytics 4

In Google Analytics 4, bounce rate is calculated differently than it was in Universal Analytics. A session bounces when a user lands on a page and leaves without triggering any engagement events — like page views, scrolls, or custom events. If your event tracking isn't set up correctly, you'll get misleading bounce rate numbers, and you won't know if users are actually engaging with your site.

Set Up Event Tracking to Measure Bounce Rate Correctly

Bounce rate in GA4 is calculated from engagement metrics. A session is considered engaged if it lasts longer than 10 seconds, generates at least 2 page views, or triggers a conversion event. If you haven't configured events properly, GA4 won't register user engagement — and everyone will look like a bounce.

Step 1: Initialize gtag.js with Your GA4 Property

Add the Google tag to your website's HTML. Replace G-XXXXXXXXXX with your Google Analytics 4 Measurement ID (found in Admin > Data Streams). This ensures all events are sent to your GA4 property.

javascript
<!-- Add to the <head> of your HTML -->
<script async src="https://www.googletagmanager.com/gtag/js?id=G-XXXXXXXXXX"></script>
<script>
  window.dataLayer = window.dataLayer || [];
  function gtag(){dataLayer.push(arguments);}
  gtag('js', new Date());
  gtag('config', 'G-XXXXXXXXXX', {
    'anonymize_ip': true,
    'allow_google_signals': true,
    'page_title': document.title,
    'page_path': window.location.pathname
  });
</script>
Initialize GA4 with your Measurement ID. GA4 automatically sends page_view events with this setup.

Step 2: Track Custom Engagement Events

Beyond page views, track actions that indicate user engagement — like button clicks, form submissions, video plays, or scroll depth. Use gtag('event', 'event_name', {...}) to send custom events to GA4. Each event resets the bounce detection and registers the session as engaged.

javascript
// Track a button click
const button = document.getElementById('cta-button');
button.addEventListener('click', function() {
  gtag('event', 'button_click', {
    'button_name': 'Download Report',
    'button_location': 'hero_section'
  });
});

// Track a form submission
const form = document.getElementById('signup-form');
form.addEventListener('submit', function() {
  gtag('event', 'form_submit', {
    'form_name': 'newsletter_signup',
    'form_location': 'sidebar'
  });
});
Send custom events when users interact with your page. These events prevent the session from being counted as a bounce.

Step 3: Test Event Firing with Tag Assistant

Install the Google Tag Assistant Chrome extension to verify that events are firing correctly to your GA4 property. Open Tag Assistant > Summary and perform actions on your site. You should see page_view and your custom events appearing in real time. If events aren't firing, check your gtag configuration and event listeners.

javascript
// Check if gtag is loaded and working
if (typeof gtag !== 'undefined') {
  console.log('gtag is loaded');
  // Send a test event
  gtag('event', 'test_event', {
    'test_value': 'tracking_working'
  });
} else {
  console.error('gtag not loaded. Check your Google tag snippet.');
}
Verify gtag is initialized before sending events. Use your browser's console to debug tracking issues.
Watch out: GA4 requires at least 10 seconds of session duration, 2 page views, or a conversion event to register engagement. A user who lands, reads your page for 5 seconds, and leaves will be counted as a bounce — even if they engaged.

View Bounce Rate in Google Analytics 4

Once your events are tracking, bounce rate appears automatically in GA4's engagement reports. GA4 calculates it as: Bounce Rate = 1 - (Engaged Sessions / Total Sessions).

Step 1: Access the Engagement Report

In GA4, go to Reports > Engagement > Overview. You'll see Bounce Rate displayed as a percentage card near the top. This is the standard bounce rate for your entire site during the selected date range. Below that, the Engagement Overview table breaks down bounce rate by landing page, traffic source, or device.

javascript
// Fetch bounce rate via Google Analytics Data API v1beta
const propertyId = 'PROPERTY_ID'; // From Admin > Property Settings
const accessToken = 'YOUR_ACCESS_TOKEN';

const body = {
  dateRanges: [
    {
      startDate: '2024-03-01',
      endDate: '2024-03-31'
    }
  ],
  metrics: [
    { name: 'bounceRate' },
    { name: 'sessions' },
    { name: 'engagedSessions' }
  ]
};

const response = await fetch(
  `https://analyticsdata.googleapis.com/v1beta/properties/${propertyId}:runReport`,
  {
    method: 'POST',
    headers: {
      'Authorization': `Bearer ${accessToken}`,
      'Content-Type': 'application/json'
    },
    body: JSON.stringify(body)
  }
);

const data = await response.json();
console.log('Bounce Rate:', data.rows[0].metricValues[0].value + '%');
Use the Data API to programmatically fetch bounce rate. Requires OAuth2 credentials with analytics.google.com scope.

Step 2: Filter by Page Path or Traffic Source

In the Engagement > Overview report, click Add comparison or Dimensions to filter bounce rate by Page Path, Traffic Source, Device, or Country. For example, filter by Page Path to see which pages have the highest bounce rates. This helps you identify underperforming pages and prioritize optimization.

javascript
// Fetch bounce rate by page path (descending)
const body = {
  dateRanges: [
    {
      startDate: '2024-03-01',
      endDate: '2024-03-31'
    }
  ],
  metrics: [
    { name: 'bounceRate' },
    { name: 'sessions' }
  ],
  dimensions: [
    { name: 'pagePath' }
  ],
  orderBys: [
    {
      metric: { metricName: 'bounceRate' },
      desc: true
    }
  ],
  limit: 10
};

const response = await fetch(
  `https://analyticsdata.googleapis.com/v1beta/properties/${propertyId}:runReport`,
  {
    method: 'POST',
    headers: {
      'Authorization': `Bearer ${accessToken}`,
      'Content-Type': 'application/json'
    },
    body: JSON.stringify(body)
  }
);

const data = await response.json();
data.rows.forEach(row => {
  const page = row.dimensionValues[0].value;
  const bounceRate = row.metricValues[0].value;
  console.log(`${page}: ${bounceRate}% bounce rate`);
});
Query bounce rate by dimension to find your highest-bounce pages. Sort by bounceRate in descending order to prioritize fixes.
Tip: GA4's bounce rate is the inverse of engagement rate. A page with 50% bounce rate has 50% engaged sessions. This is different from Universal Analytics, where bounce rate was about visitors who triggered only one hit.

Create Segments to Understand Bounce Behavior

Bounce rate alone doesn't tell the whole story. Use GA4 segments to isolate bounced sessions and understand why they're happening.

Step 1: Create a Bounced Sessions Segment

In GA4, go to Reports > Segments and click Create Segment. Set the condition to Engaged Sessions = 0 or Session Duration < 10 seconds. Name it Bounced Sessions. Apply this segment to any report to see only traffic that didn't engage. This helps you compare bounced vs. engaged users across dimensions like traffic source, device, or landing page.

javascript
// Fetch bounced sessions (engagedSessions = 0)
const body = {
  dateRanges: [
    {
      startDate: '2024-03-01',
      endDate: '2024-03-31'
    }
  ],
  metrics: [
    { name: 'sessions' }
  ],
  dimensions: [
    { name: 'sessionSourceMedium' }
  ],
  dimensionFilter: {
    andGroup: {
      expressions: [
        {
          filter: {
            fieldName: 'engagedSessions',
            numericFilter: {
              operation: 'EQUAL',
              value: { int64Value: '0' }
            }
          }
        }
      ]
    }
  },
  orderBys: [
    {
      metric: { metricName: 'sessions' },
      desc: true
    }
  ]
};

const response = await fetch(
  `https://analyticsdata.googleapis.com/v1beta/properties/${propertyId}:runReport`,
  {
    method: 'POST',
    headers: {
      'Authorization': `Bearer ${accessToken}`,
      'Content-Type': 'application/json'
    },
    body: JSON.stringify(body)
  }
);

const data = await response.json();
data.rows.forEach(row => {
  console.log(`${row.dimensionValues[0].value}: ${row.metricValues[0].value} bounced sessions`);
});
Use the Data API to filter for bounced sessions (engagedSessions = 0) and analyze them by traffic source.

Step 2: Compare Bounce Rates by Traffic Source

Add Source/Medium as a dimension to your bounce rate report. This shows you which traffic sources have the highest bounce rates. For example, if organic search has 70% bounce rate but direct traffic has 30%, it signals a problem with your landing pages or keyword-to-page relevance. Use this insight to refine your content strategy and landing page targeting.

javascript
// Bounce rate by traffic source
const body = {
  dateRanges: [
    {
      startDate: '2024-03-01',
      endDate: '2024-03-31'
    }
  ],
  metrics: [
    { name: 'bounceRate' },
    { name: 'sessions' }
  ],
  dimensions: [
    { name: 'sessionSourceMedium' }
  ],
  orderBys: [
    {
      metric: { metricName: 'bounceRate' },
      desc: true
    }
  ]
};

const response = await fetch(
  `https://analyticsdata.googleapis.com/v1beta/properties/${propertyId}:runReport`,
  {
    method: 'POST',
    headers: {
      'Authorization': `Bearer ${accessToken}`,
      'Content-Type': 'application/json'
    },
    body: JSON.stringify(body)
  }
);

const data = await response.json();
data.rows.forEach(row => {
  const source = row.dimensionValues[0].value;
  const bounceRate = row.metricValues[0].value;
  const sessions = row.metricValues[1].value;
  console.log(`${source}: ${bounceRate}% bounce rate (${sessions} sessions)`);
});
Identify which traffic sources drive the most bounces. High-bounce sources may indicate keyword mismatch or poor UX for that audience.

Common Pitfalls

  • Forgetting that GA4's bounce rate calculation changed from Universal Analytics. In GA4, engagement time and multiple page views matter; in UA, it was about raw hits. Don't compare bounce rate trends across tools without adjusting your expectations.
  • Not configuring custom events for user engagement. If you only rely on page_view events, your bounce rate will be artificially high. Add scroll events, button clicks, and form submissions to get an accurate picture.
  • Assuming a high bounce rate is always bad. A single-page blog post or landing page might legitimately have a 70% bounce rate if users find what they need and leave. Analyze bounce rate alongside time on page and conversion rate to understand context.
  • Overlooking the 10-second engagement rule. Sessions under 10 seconds with no events are always counted as bounces in GA4, even if the user read the page. If your pages load slowly, your bounce rate will reflect that.

Wrapping Up

Bounce rate in GA4 is calculated from engagement metrics, so proper event tracking is essential. Set up gtag.js with custom events, view your bounce rate in the Engagement report, and use the Data API to analyze bounce patterns by page, source, or device. If you want to track bounce rate automatically across Google Analytics 4 and other analytics tools, Product Analyst can help.

Track these metrics automatically

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

Try Product Analyst — Free