6 min read

How to Set Up Alerts for Session Duration in Google Analytics 4

When session duration tanks unexpectedly, you lose time waiting for your weekly report. Google Analytics 4 lets you set up real-time alerts so you catch drops before they impact your business. We'll walk through configuring custom alerts for session duration.

Create a Custom Alert in GA4

GA4's custom alerts let you monitor session duration and trigger email notifications when it crosses a threshold you define.

Navigate to Custom Alerts

In GA4, open Admin (bottom left), then select Custom Alerts from the Property section. Click Create Alert.

javascript
// GA4 custom alert configuration object
// This represents the alert you're creating in the UI

const customAlert = {
  displayName: 'Session Duration Drop Alert',
  description: 'Alert when avg session duration falls below 3 minutes',
  conditions: [
    {
      metricName: 'averageSessionDuration',
      threshold: 180, // 180 seconds = 3 minutes
      comparisonType: 'LESS_THAN', // LESS_THAN, GREATER_THAN, PERCENT_CHANGE
      triggersOn: 'THRESHOLD_FIRST_TOUCH' // Fire on first trigger only
    }
  ],
  alertChannelNames: [
    'projects/YOUR-PROJECT-ID/notificationChannels/CHANNEL-ID'
  ]
};
GA4 custom alert structure

Configure the metric and threshold

Select Average Session Duration from the metric dropdown. Choose your comparison type: drops below (LESS_THAN), exceeds (GREATER_THAN), or changes by X% (PERCENT_CHANGE). Enter your threshold value.

Set notification preferences

Add email addresses and choose how often you want to be notified—daily, weekly, or on first trigger. If you use Google Cloud, you can integrate Slack or PagerDuty via notification channels.

javascript
// Notification settings for your custom alert
const notificationSettings = {
  emailAddresses: ['[email protected]', '[email protected]'],
  frequency: 'DAILY', // DAILY, WEEKLY, ON_FIRST_TOUCH
  timezone: 'America/New_York',
  deliveryChannel: 'EMAIL'
};

// For Slack/PagerDuty integration via Google Cloud
const cloudIntegration = {
  notificationChannels: [
    'projects/YOUR-PROJECT-ID/notificationChannels/SLACK-CHANNEL-ID'
  ]
};
Configuring alert delivery and frequency

Save and verify

Click Save Alert. GA4 displays your alert in the list. It will fire based on your threshold when daily data is processed (usually by noon UTC the next day).

Watch out: Custom alerts fire on daily aggregated data, not real-time. A session duration drop at 10 AM won't trigger an alert until the next day. Use the Data API (next section) for hourly or minute-level monitoring.

Build Real-Time Alerts with the Data API

For immediate, custom alerting logic, query session duration directly from the Data API and trigger alerts on your own schedule.

Install and initialize the Data API client

Install the Google Analytics Data API library. You'll need a service account with access to your GA4 property.

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

const serviceAccountKey = JSON.parse(
  fs.readFileSync('./service-account-key.json')
);

const client = new BetaAnalyticsDataClient({
  credentials: serviceAccountKey
});

const propertyId = '123456789'; // Replace with your GA4 property ID
Initializing the Google Analytics Data API client

Query session duration for the current period

Call runReport() to fetch average session duration. Compare today's value to yesterday's or the 7-day average to detect drops. You can segment by traffic source, device, or landing page.

javascript
async function checkSessionDuration() {
  const [response] = await client.runReport({
    property: `properties/${propertyId}`,
    dateRanges: [
      {
        startDate: 'today',
        endDate: 'today'
      },
      {
        startDate: 'yesterday',
        endDate: 'yesterday'
      }
    ],
    metrics: [
      {
        name: 'averageSessionDuration' // Measured in seconds
      },
      {
        name: 'sessions'
      }
    ],
    dimensions: [
      {
        name: 'date'
      }
    ]
  });

  const todayRow = response.rows[0];
  const yesterdayRow = response.rows[1];

  const todayDuration = parseFloat(todayRow.metricValues[0].value);
  const yesterdayDuration = parseFloat(yesterdayRow.metricValues[0].value);
  const todaySessions = parseInt(todayRow.metricValues[1].value);

  return {
    today: todayDuration,
    yesterday: yesterdayDuration,
    sessions: todaySessions
  };
}

const data = await checkSessionDuration();
console.log(`Today: ${data.today.toFixed(0)}s | Yesterday: ${data.yesterday.toFixed(0)}s`);
Querying session duration with the Data API

Trigger alerts based on your logic

Compare today's average to yesterday's or a rolling baseline. Calculate the percentage drop. If it exceeds your threshold, send an alert to Slack, email, or your monitoring system.

javascript
async function sendAlertIfDropped() {
  const data = await checkSessionDuration();
  const threshold = 180; // 3 minutes in seconds
  const percentDropThreshold = 15; // Alert if drops 15%+

  if (data.today < threshold) {
    const dropPercent = ((data.yesterday - data.today) / data.yesterday * 100).toFixed(1);
    
    // Send to Slack
    await fetch('https://hooks.slack.com/services/YOUR-WEBHOOK-URL', {
      method: 'POST',
      body: JSON.stringify({
        text: `⚠️ Session Duration Alert`,
        blocks: [
          {
            type: 'section',
            text: {
              type: 'mrkdwn',
              text: `*Session Duration Dropped*\nToday: ${data.today.toFixed(0)}s (${data.sessions} sessions)\nYesterday: ${data.yesterday.toFixed(0)}s\nChange: -${dropPercent}%`
            }
          }
        ]
      })
    });

    console.error(`Alert fired: ${dropPercent}% drop detected`);
  }
}

// Run every hour via Cloud Scheduler, Lambda, or cron
sendAlertIfDropped();
Implementing custom alert logic with the Data API
Tip: Segment session duration by traffic source (trafficSource) or device (deviceCategory) to isolate the problem. A drop in mobile session duration is different from desktop—your alert should reflect that.

Common Pitfalls

  • GA4 custom alerts fire on daily data, which is processed by noon UTC the next day. Real-time monitoring requires the Data API and a scheduled job (Cloud Scheduler, Lambda, or cron).
  • Session duration includes only sessions with engagement events (clicks, scrolls, page views). Bot traffic and direct visitors with no interactions may skew your metrics. Filter bot traffic in your GA4 view or via the Data API.
  • Average session duration changed when you adjusted the session timeout setting. If you changed this from 30 minutes to 15 minutes, your baseline shifts. Recalibrate alert thresholds after session timeout changes.
  • The averageSessionDuration metric is undefined if you have zero sessions. Alerts won't fire on properties with no data. Verify traffic is reaching your GA4 view before troubleshooting.

Wrapping Up

You now have two paths: use GA4's built-in custom alerts for daily notifications, or build custom alerts with the Data API for real-time, segment-specific monitoring. Combine both approaches—daily UI alerts for baseline changes and programmatic alerts for immediate issues. If you want to track this automatically across 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