If you're building a SaaS product or content platform, you need to know what percentage of visitors are actually engaging with your content or features. GA4 calculates engagement rate automatically, but the definition might surprise you—it's different from GA3, and if your events aren't set up right, your numbers won't tell the real story.
How GA4 Defines Engagement
GA4 marks a session as 'engaged' based on three criteria. Understanding these rules is critical because they determine whether your engagement rate reflects reality.
Know the engagement criteria
A session counts as engaged in GA4 if any of these happen: the user stays on-site for more than 10 seconds, triggers a conversion event, or visits 2+ pages. If none of those occur, it's a non-engaged session. This is GA4's replacement for GA3's bounce rate—it's stricter about what counts.
// GA4 engagement tracking happens automatically, but mark key actions as conversions
// by sending them with gtag.js
gtag('event', 'sign_up', {
'method': 'google'
});
gtag('event', 'purchase', {
'value': 99.99,
'currency': 'USD',
'transaction_id': 'T-12345'
});
gtag('event', 'view_item', {
'items': [
{
'item_id': '12345',
'item_name': 'Premium Plan',
'price': 99.99
}
]
});Check your engagement rate in GA4
Navigate to Reports > Engagement > Overview in your GA4 property. The top metric shows your overall engagement rate. Drill down by Device, Country, Traffic Source, or other dimensions to see where engagement is strong and where it's weak. This is the fastest way to spot problems.
// Verify your GA4 property is set up correctly using the Admin API
const analyticsadmin = require('@google-analytics/admin');
const {AnalyticsAdminServiceClient} = analyticsadmin;
const client = new AnalyticsAdminServiceClient();
async function checkProperty(propertyId) {
const request = {
name: `properties/${propertyId}`,
};
const [property] = await client.getProperty(request);
console.log(`Property: ${property.displayName}`);
console.log(`Timezone: ${property.timeZoneId}`);
}Query Engagement Rate Programmatically
For dashboards, reports, or custom analysis, pull engagement rate directly from GA4 using the Data API. This method scales better than manual checks in the UI.
Initialize the Data API client
Install the @google-analytics/data package and authenticate with a service account. You'll need a service account JSON key from Google Cloud with read access to your GA4 property.
const {BetaAnalyticsDataClient} = require('@google-analytics/data');
const client = new BetaAnalyticsDataClient({
keyFilename: './service-account-key.json',
});
const propertyId = '123456789'; // Your GA4 property ID
const request = {
property: `properties/${propertyId}`,
};Fetch engagement rate and related metrics
Call runReport() with the engagementRate metric. Include engagedSessions and sessions to calculate the breakdown yourself if needed. You can slice by Country, Device Category, Source, or other dimensions.
async function getEngagementRate(propertyId, startDate, endDate) {
const request = {
property: `properties/${propertyId}`,
dateRanges: [
{
startDate: startDate,
endDate: endDate,
},
],
metrics: [
{ name: 'engagementRate' },
{ name: 'sessions' },
{ name: 'engagedSessions' },
],
dimensions: [
{ name: 'country' },
{ name: 'deviceCategory' },
],
};
const [response] = await client.runReport(request);
response.rows.forEach(row => {
const country = row.dimensionValues[0].value;
const device = row.dimensionValues[1].value;
const engagementRate = parseFloat(row.metricValues[0].value);
const sessions = row.metricValues[1].value;
console.log(`${country} - ${device}: ${(engagementRate * 100).toFixed(2)}% (${sessions} sessions)`);
});
}
getEngagementRate('123456789', '2025-03-01', '2025-03-26');Calculate custom engagement definitions
If you want a tighter definition—like only counting sessions with page_view AND add_to_cart events—pull eventCount for specific events and compute your own ratio. Use dimension filters to narrow events to what matters.
async function customEngagement(propertyId, startDate, endDate) {
// Count sessions that had a high-value event
const request = {
property: `properties/${propertyId}`,
dateRanges: [
{ startDate: startDate, endDate: endDate },
],
metrics: [
{ name: 'sessions' },
{ name: 'eventCount' },
],
dimensions: [
{ name: 'eventName' },
],
dimensionFilter: {
filter: {
fieldName: 'eventName',
stringFilter: {
matchType: 'EXACT',
value: 'add_to_cart',
},
},
},
};
const [response] = await client.runReport(request);
let highValueEvents = 0;
response.rows.forEach(row => {
highValueEvents += parseInt(row.metricValues[1].value);
});
// Get total sessions for ratio
const allSessions = 5000; // Fetch separately
const customEngagementRate = (highValueEvents / allSessions).toFixed(4);
console.log(`Custom engagement (add_to_cart): ${(customEngagementRate * 100).toFixed(2)}%`);
}
customEngagement('123456789', '2025-03-01', '2025-03-26');engagementRate against engagedSessions and sessions totals. If engagement rate is 0% but you have sessions, your events aren't being sent or GA4 isn't receiving them.Common Pitfalls
- Confusing the 10-second rule with GA3's 30-minute session timeout. In GA4, 9 seconds and a page exit = non-engaged, even if the user clicked five buttons.
- GA4 calculates engagement at the session level, not the user level. A single user can have multiple sessions with wildly different engagement rates.
- Not marking your product-critical actions as conversion events. GA4 won't weight a sign-up or high-value purchase toward engagement unless you explicitly tag it as a conversion in Admin > Conversions.
- Looking at engagement rate over 1–2 days and panicking about the number. GA4 needs at least a week of data to smooth out noise and give you actionable trends.
Wrapping Up
GA4's engagement rate is simple once you internalize the rules: 10+ seconds on-site, 2+ pages, or a conversion event. Check it in the Reports > Engagement section for quick insights, or use the Data API to pull it into a dashboard or BI tool. If you need to track engagement across GA4, Amplitude, Mixpanel, and other analytics platforms in one place, Product Analyst can help.