6 min read

How to Track Funnel Analysis in PostHog

Funnel analysis shows where users drop off in your conversion journey. PostHog makes it easy to track every step—from signup to payment—and spot exactly where people abandon. You just need to emit the right events and wire them together.

Capture Events for Your Funnel Steps

Before you can analyze a funnel, you need events. These are the milestones users hit as they move through your app.

Initialize PostHog and capture signup events

Load the PostHog SDK in your app and call posthog.capture() when users complete each funnel step. For a signup flow, capture an event when users hit the signup form, enter their email, and create their account.

javascript
import posthog from 'posthog-js';

posthog.init('your-api-key', {
  api_host: 'https://us.posthog.com',
});

posthog.capture('signup_form_viewed');
posthog.capture('account_created', {
  plan: 'pro',
  signup_method: 'email',
});
posthog.capture('first_login', {
  user_id: user.id,
});
PostHog SDK event capture for a signup funnel

Add context with event properties

Include properties on each event to segment your funnel later. Pass user info, plan type, or traffic source. This lets you answer: Do mobile users drop off more than desktop users? Do free-trial users convert differently?

javascript
posthog.capture('onboarding_completed', {
  step: 'data_connected',
  source: 'marketing_campaign',
  days_since_signup: 2,
  feature_accessed: 'dashboard',
});

posthog.capture('created_first_chart', {
  chart_type: 'line',
  data_source: 'amplitude',
  time_to_first_chart: 45,
});
Event properties for detailed funnel segmentation

Identify users so PostHog links events together

Call posthog.identify() with a unique user ID so PostHog connects all their events across sessions. Without this, PostHog treats each session as a different user and your funnel metrics become meaningless.

javascript
posthog.identify('user-123', {
  email: '[email protected]',
  company: 'ACME Corp',
  plan: 'enterprise',
});

posthog.capture('dashboard_viewed');
posthog.capture('exported_report');
Identify users so funnel events are tied to individuals
Watch out: If you don't call posthog.identify() before capturing events, PostHog treats each page load as a different user. Your funnel dropoff will look terrible because it's actually summing strangers' sessions.

Build Your Funnel in PostHog

Once events are flowing, open PostHog and create a funnel to visualize the conversion path.

Create a funnel in the Insights tab

In PostHog, go to Insights and select Funnel. Click Add funnel step and pick the events that define your conversion path. Order matters—first event is your entry, last is your goal.

javascript
// Example: Define a checkout funnel via API
const funnel = {
  insight: 'FUNNELS',
  funnel_viz_type: 'steps',
  funnel_order_type: 'ordered',
  events: [
    { id: 'product_viewed', order: 0 },
    { id: 'cart_opened', order: 1 },
    { id: 'checkout_started', order: 2 },
    { id: 'payment_submitted', order: 3 },
  ],
};

// POST /api/projects/{project_id}/insights/
Funnel structure in PostHog (UI or API)

Segment your funnel by user properties

Click Add filter to split your funnel by a property like plan type, source, or browser. This reveals whether your funnel looks different for different user groups. A mobile user might drop off at checkout while desktop users convert fine.

javascript
// Segment funnel by traffic source via API
const filteredFunnel = {
  events: [
    { id: 'signup_form_viewed', order: 0 },
    { id: 'account_created', order: 1 },
  ],
  properties: [
    {
      key: 'source',
      operator: 'exact',
      value: 'paid_search',
      type: 'event',
    },
  ],
};
Filter funnels by properties to segment user behavior

Set a time window for your funnel

By default, PostHog tracks funnel steps across all time. But you probably want to ask: How many users complete the entire funnel within 7 days of signup? Use the Funnel window setting to define how long a user has to complete each step.

javascript
// Set a 7-day funnel window via API
const funnel = {
  insight: 'FUNNELS',
  funnel_window_days: 7,
  events: [
    { id: 'account_created', order: 0 },
    { id: 'first_dashboard_view', order: 1 },
    { id: 'chart_created', order: 2 },
  ],
};
Funnel window limits how long users have to complete steps
Tip: Name your events clearly: payment_submitted is better than submit. Avoid events that fire multiple times per user (like page_viewed). Funnel steps work best with meaningful milestone events.

Interpret and Act on Funnel Data

Your funnel is live. Now you need to spot dropoff, understand why, and fix it.

Read the funnel breakdown and conversion rates

PostHog shows conversion rate between each step—e.g., 75% of signups reach the onboarding screen, but only 40% create their first chart. The wider the gap, the bigger the problem. Click on a step to see the users who dropped off and drill into their session replays.

javascript
// Query funnel conversion rates via API
const response = await fetch(
  'https://us.posthog.com/api/projects/your-project-id/insights/',
  {
    headers: {
      Authorization: `Bearer your-personal-api-key`,
    },
  }
);

const funnels = await response.json();
// Returns conversion_rates: [0.8, 0.6, 0.4] for 3-step funnel
Retrieve funnel metrics programmatically

Test changes by creating multiple funnel views

Clone your funnel and add filters for different user segments or time periods. Run one for paid users, one for free users. Run one for this month vs. last month. Compare the conversion rates to understand what's working.

javascript
// Capture event that tracks an A/B test variant
posthog.capture('checkout_viewed', {
  variant: 'new_simplified_form',
});

// Later, in PostHog UI, filter funnels by:
// variant = 'new_simplified_form'
// This shows if the new form improves funnel completion
Track variants in events, then segment funnels to measure impact

Monitor funnel trends with regular reviews

Save your funnel view to your dashboard and check it weekly. Look for conversion rate drops—if signup-to-first-login dropped from 60% to 40%, something broke. Pin the funnel for ongoing monitoring.

javascript
// Save a funnel to your dashboard
const saved_insight = {
  name: 'Checkout Funnel - Weekly Review',
  insight_type: 'FUNNELS',
  events: [
    { id: 'checkout_started', order: 0 },
    { id: 'payment_submitted', order: 1 },
    { id: 'order_confirmed', order: 2 },
  ],
  saved: true,
};

// POST /api/projects/{project_id}/insights/
Save funnels to your dashboard for ongoing monitoring
Watch out: Funnel windows are tricky. If your window is too short (1 day), users won't have time to complete steps and you'll see artificially low conversion. If it's too long (90 days), you'll include users who abandoned long ago. Start with 7 days and adjust based on your actual user journey.

Common Pitfalls

  • Forgetting to call posthog.identify() before capturing events—PostHog will treat each page load as a separate user, destroying your funnel metrics.
  • Using events that fire too frequently (like page_viewed) as funnel steps—users hit these hundreds of times, so conversion rates become meaningless.
  • Setting a funnel window that's too short, making it impossible for users to complete steps naturally—a 1-day window for a 2-week onboarding journey will show 0% conversion.
  • Not capturing event properties—you won't be able to segment your funnel by source, device, or plan type later, and you'll miss crucial dropoff patterns.

Wrapping Up

You now have a working funnel in PostHog that shows exactly where users drop off. Watch it weekly, test changes with variants, and act on the data. If you want to track funnels automatically across all your tools and get alerts when conversion dips, Product Analyst can help.

Track these metrics automatically

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

Try Product Analyst — Free