6 min read

What Is Session Duration in PostHog

Session duration tells you how long users spend in your app before they leave. It's one of the most direct signals of engagement—if sessions are short, users aren't finding value. PostHog makes it easy to track, segment, and act on this data without extra setup.

What Session Duration Actually Means

Session duration isn't just time on page—it's the complete interaction window.

Understand how PostHog calculates sessions

PostHog groups events into a session automatically. A session starts when a user first appears and ends after 30 minutes of inactivity (this is the default, but you can customize it). All events within that window count toward one session. So if a user loads your app, browses for 8 minutes, pauses for 10 minutes, then browses for 2 more minutes, that's one 20-minute session (not 18 + 2).

javascript
// PostHog automatically tracks sessions—no setup needed
// Just initialize the SDK and session_id is captured with every event
posthog.init('phc_YOUR_PROJECT_KEY', {
  api_host: 'https://us.i.posthog.com',
  // session_timeout_seconds: 1800 // default 30 min, customize if needed
});
PostHog tracks sessions by default—you just initialize the SDK

See where sessions appear in your data

In Events, every row includes a $session_id property. In Insights, when you create a Trends or Retention chart, PostHog automatically aggregates by session. You'll see metrics like Average Session Duration, Max Session Duration, and Total Sessions available out of the box in the Metrics dropdown.

javascript
// Access session info in your events (read-only—you don't set this manually)
const event = {
  event: 'page_view',
  properties: {
    $session_id: 'sess_1a2b3c4d5e6f7g8h', // auto-captured
    current_url: window.location.href
  }
};
posthog.capture(event.event, event.properties);
Session ID is auto-captured—you reference it, not set it

Measure session duration in Insights

Go to Insights > Trends. Set Data series to the event you care about (e.g., page_view). In the Metrics dropdown, select Average Session Duration. Choose your date range and filters. PostHog calculates the median and mean duration per session. You can break it down by Properties like utm_source or signup_cohort to see which users or traffic sources spend more time.

javascript
// Use the query API to fetch session duration programmatically
const response = await fetch('https://us.i.posthog.com/api/projects/PROJECT_ID/query/', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'Authorization': `Bearer ${posthog_api_key}`
  },
  body: JSON.stringify({
    query: {
      kind: 'TrendsQuery',
      dateRange: { date_from: '-30d' },
      series: [{
        kind: 'EventsNode',
        event: 'page_view',
        math: 'avg_duration'
      }]
    }
  })
});
const result = await response.json();
Query API example for programmatic access to session metrics
Watch out: If you're tracking SPAs (single-page apps), page_view may not fire on route changes. Use a custom event like navigation or verify that your routing library is triggering page_view correctly.

Why Session Duration Matters and How to Use It

Session duration reveals whether users find your product sticky.

Compare session duration across user segments

Not all users are created equal. In Insights, add a filter like signup_source = 'organic' or user_cohort = 'trial'. Then break down by Properties to see if free-tier users have shorter sessions than paid users. If paying users spend 2x longer in your app, you've found a retention lever. This directly informs your pricing and feature strategy.

javascript
// Tag users with custom properties so you can segment later
posthog.identify('user_123', {
  signup_source: 'organic',
  plan: 'enterprise',
  customer_segment: 'tech_founder',
  onboarding_complete: true
});

// Now you can filter on these in Insights → "plan = enterprise"
Identify users with properties to enable segmentation in Insights

Track drop-off in session funnels

Go to Insights > Funnels. Add steps like page_viewfeature_usedupgrade_clicked. PostHog shows you where sessions drop. If 80% of sessions include a page_view but only 20% include upgrade_clicked, that's a conversion leak you can optimize. Session duration combined with funnel analysis tells you *when* users are leaving.

javascript
// Capture milestones within a session
posthog.capture('feature_used', {
  feature_name: 'dashboard',
  time_to_feature: 45 // seconds from session start
});

posthog.capture('upgrade_clicked', {
  plan: 'pro',
  session_time_at_click: 120 // seconds from session start
});
Track specific moments in the session to correlate with engagement
Tip: Low average session duration + high bounce rate usually means a UX or messaging issue, not a feature gap. Validate with user interviews before investing in new features.

Customizing Session Behavior

PostHog's 30-minute default works for most apps, but you can tweak it.

Adjust session timeout for your product type

Real-time apps (chat, trading) should use shorter timeouts (5–10 min). Long-form content (docs, courses) should use longer timeouts (45–60 min). Change it in your SDK initialization. PostHog recalculates sessions retroactively for new data, but historical sessions already split are not merged—keep that in mind when comparing old vs. new data.

javascript
// Set a custom session timeout (in seconds)
posthog.init('phc_YOUR_PROJECT_KEY', {
  api_host: 'https://us.i.posthog.com',
  session_timeout_seconds: 600 // 10 minutes instead of default 30
});

// This applies only to new sessions going forward
Customize session timeout at initialization
Watch out: Changing session_timeout_seconds only affects *new* sessions. Existing sessions in your database won't be recalculated. Document the change so you don't accidentally compare incompatible time windows.

Common Pitfalls

  • Confusing session duration with time-on-page. PostHog's session spans *all* events until inactivity, not a single page view.
  • Not tagging events with custom properties. Generic events like page_view are useful, but only page_view + user segment tells you the full story.
  • Forgetting that SPAs don't fire page_view on route changes. If your app is a single-page app, create a custom navigation event or verify your library emits page_view correctly.
  • Changing session timeout and comparing across time periods without accounting for the methodological shift. It'll break your time-series analysis.

Wrapping Up

Session duration is PostHog's window into user engagement. It's immediate, actionable, and requires no setup—the SDK captures it automatically. Use it to spot which user segments stick around, where funnels leak, and whether your onboarding actually works. 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