Skip to content
Telemetry
Browse docs
Discussion TopicsUpdated July 28, 2026Reviewed by the Telemetry editorial and product teams2 min read

Use this doc with your coding agent

Open a focused prompt pack for Claude Code, Codex, Cursor, or another coding agent, then adapt it to the workflow covered here.

SQL Funnel Analysis

A funnel measures how a defined population progresses through milestones. The SQL is straightforward only after the product definition is precise: who enters, whether steps must occur in order, how long users have to progress, which identity represents a person or account, and how retries and duplicate events behave.

Reduce events to one row per actor

WITH events AS (
  SELECT account_id, event_name, timestamp_utc
  FROM product_events
  WHERE timestamp_utc >= now() - INTERVAL '30 days'
),
signups AS (
  SELECT account_id, MIN(timestamp_utc) AS signed_up_at
  FROM events WHERE event_name = 'signup_completed'
  GROUP BY account_id
),
workspaces AS (
  SELECT s.account_id, s.signed_up_at,
    MIN(e.timestamp_utc) AS workspace_created_at
  FROM signups AS s
  LEFT JOIN events AS e ON e.account_id = s.account_id
    AND e.event_name = 'workspace_created'
    AND e.timestamp_utc >= s.signed_up_at
  GROUP BY s.account_id, s.signed_up_at
),
account_steps AS (
  SELECT w.account_id, w.signed_up_at, w.workspace_created_at,
    MIN(e.timestamp_utc) AS first_event_sent_at
  FROM workspaces AS w
  LEFT JOIN events AS e ON e.account_id = w.account_id
    AND e.event_name = 'first_event_sent'
    AND e.timestamp_utc >= w.workspace_created_at
  GROUP BY w.account_id, w.signed_up_at, w.workspace_created_at
)
SELECT
  COUNT(*) AS accounts_seen,
  COUNT(signed_up_at) AS signed_up,
  COUNT(workspace_created_at) AS created_workspace,
  COUNT(first_event_sent_at) AS sent_first_event
FROM account_steps;

Each stage keeps one row per account and selects the first milestone at or after the previous eligible stage. A missing or out-of-order milestone blocks every later stage; a later valid retry can still advance the account. Duplicate events count once, and equal timestamps are accepted. Add a maximum conversion window when progression must happen within a fixed period.

Keep cohort and observation windows distinct

If the query includes signups from yesterday, those accounts have had less time to activate than accounts from the start of the month. Either allow every cohort a complete observation window or label recent cohorts as incomplete. Filtering all events to the same calendar range can unintentionally cut off valid later milestones.

Choose an account identifier for account-level activation and a user identifier for person-level behavior. Do not switch identities between steps. Define how merged accounts, anonymous sessions, reopened accounts, and repeated completions work.

Always show step counts beside percentages. A conversion change can come from the numerator, denominator, traffic mix, or instrumentation. The tested signup funnel recipe and conversion-rate guide provide a complete starting point. Use Cohort Retention when the question is continued behavior after activation.

Related product capability

Run read-only DataFusion SQL over structured-event tables and reuse the result.

Ownership and technical references

The Telemetry editorial team owns this explanation; the product team reviews behavior, examples, and boundaries.

Review the editorial standard