Funnel Analysis
When to use this skill
Use when measuring sequential step-by-step conversion through a defined flow. Triggers:
- "Build a signup funnel"
- "Where are users dropping off?"
- "Conversion from step A to step B"
- "Analyze the checkout flow"
- "Activation funnel"
For lifecycle behavior over weeks/months → cohort-analysis. For experiments → ab-test-analysis.
Required inputs
| Input |
Why it matters |
| Funnel steps (ordered) |
The sequence to measure |
| Unit of analysis |
User, session, or visit |
| Time window |
Conversion deadline between steps |
| Strict vs non-strict order |
Must steps occur in order, or just all eventually? |
| Cohort filter |
Which users to include (e.g., new signups only) |
Workflow
Define the steps explicitly. Each step is an event name + filter conditions. Avoid vague steps like "engaged."
Decide strict vs non-strict ordering.
- Strict (sequential): step N must follow step N-1 in time. Standard for onboarding/checkout flows.
- Non-strict (any order): user must have done all steps eventually. Use for feature adoption funnels where order doesn't matter.
Set the conversion window. Between step N and N+1, what's the max time to convert? Common defaults:
- Same session: ~30 min
- Same day: 24h
- Same week: 7 days
- Lifetime: open-ended (but inflates conversion artificially)
Compute the funnel using scripts/build_funnel.sql, which produces:
- Step counts (users reaching each step)
- Step-to-step conversion rate
- End-to-end conversion rate
- Median time between steps
Diagnose biggest drop-offs. The largest absolute drop is usually the highest-leverage fix. Compare:
- vs benchmark (industry, prior period)
- vs segments (channel, device, plan)
Segment to find the right bucket. Compare the funnel by:
- Acquisition channel
- Device (mobile vs desktop)
- User type (new vs returning)
- Country / locale
Look for steps where conversion diverges between segments. These are the actionable insights.
Generate the three canonical visualizations using scripts/visualize_funnel.py:
- Waterfall chart — users at each step with cumulative loss overlay (end-to-end view)
- Step-to-step bar chart — per-transition conversion rate, color-coded by health
- Monthly cohort heatmap — cohort × step conversion %, to see if the funnel is improving or degrading over time
When responding inline (no PNG output), produce equivalent markdown tables for each — see reference.md for the inline templates.
Write the readout.
Output format
# Funnel Analysis: <name>
## Definitions
- Unit: <user | session>
- Cohort filter: <e.g., new signups in last 14 days>
- Ordering: <strict | non-strict>
- Conversion window: <e.g., same session, max 30 min between steps>
- Date range: <start> to <end>
## Funnel (overall)
| Step | Users | Step CR | End-to-end CR | Median time from prev |
|---|---|---|---|---|
| 1. Landing | 100,000 | — | 100% | — |
| 2. Signup | 32,000 | 32.0% | 32.0% | 1.2 min |
| 3. Email verify | 22,400 | 70.0% | 22.4% | 4.5 min |
| 4. Profile complete | 16,800 | 75.0% | 16.8% | 2.1 min |
| 5. First action | 10,080 | 60.0% | 10.1% | 14 min |
## Visualizations
### Waterfall — end-to-end conversion from step 1

Bars show users at each step; gray overlays show users lost since the previous step. Headline: 10.1% end-to-end conversion (step 1 → final).
### Step-to-step conversion

Each bar is the conversion rate from step N to step N+1 (green ≥80%, amber ≥50%, red <50%). Worst transition flagged in the diagnosis below.
### Monthly cohort heatmap

Rows = signup month, columns = funnel step, cell = % of that cohort reaching the step. Reveals whether the funnel is trending up, flat, or degrading across cohorts.
## Biggest drop-offs
1. **Landing → Signup**: -68pp drop (32% conversion). Largest absolute loss.
2. **Profile complete → First action**: -40pp drop, slowest median time (14 min) — suggests confusion or friction.
## Segment breakdowns
| Segment | Landing→Signup | Signup→Verify | Verify→Profile | Profile→First |
|---|---|---|---|---|
| Mobile | 28% | 65% | 73% | 52% |
| Desktop | 38% | 78% | 78% | 68% |
| Paid search | 35% | 72% | 76% | 64% |
| Organic | 24% | 68% | 73% | 55% |
**Key finding:** Mobile users underperform desktop at every step. Largest mobile gap is at "first action" (52% vs 68%) — suggests post-signup mobile experience friction.
## Interpretation
- The single biggest leverage point is landing → signup (-68pp). Even a 2pp improvement = 2,000 more weekly signups.
- However, the most actionable opportunity is **mobile first-action** because the gap vs desktop is large and the cohort is high-intent (already signed up).
## Caveats
- "First action" definition: <event spec>
- Users counted at most once per step (deduplicated by user_id)
- Mobile = iOS + Android combined; gap may differ by OS
## Next steps
- Run heatmap analysis on mobile post-signup screens
- Pre-register an A/B test on the signup form (see `ab-test-design`)
Validation checks
Edge cases & failure modes
- Skipped steps: in non-strict funnels, a user might skip step 3 and do step 4. Decide if they "count" for step 3. Default: no, they don't.
- Re-entries: user does step 1, abandons, comes back next day and does step 1 again. Count first instance only (use min event timestamp).
- Lifetime windows inflate conversion: a 30-day window will show higher conversion than 1-day, but the trailing days are mostly "users who eventually got around to it" rather than directly attributable to the funnel design.
- Survivorship at later steps: late steps have small N — small absolute changes look like big percentage shifts. Show absolute counts alongside rates.
- Step granularity: too granular (10+ steps) makes drop-off diagnosis impossible. Roll up. 4-6 steps is the sweet spot.
Scripts
scripts/build_funnel.sql — Snowflake template for strict-ordered funnel with time-bounded steps.
scripts/visualize_funnel.py — Produces the three canonical PNGs (waterfall, step-to-step, cohort heatmap) from a long-format events CSV.
python scripts/visualize_funnel.py \
--input events.csv \
--steps landing,signup,email_verify,profile_complete,first_action \
--output-dir charts/ \
--cohort-grain month \
--strict
Related skills
cohort-analysis — for lifecycle behavior over weeks/months
metric-definition — pin down each step's event definition
ab-test-design — test a fix to the biggest drop-off
data-quality-audit — sanity-check the event sources before trusting the funnel
1---2name: funnel-analysis3description: Builds step-by-step funnel analyses with conversion rates, drop-off diagnosis, and segmentation. Use when the user mentions funnel, conversion rate, drop-off, signup-to-activation, step-by-step conversion, onboarding flow, or "where are users falling off."4---56# Funnel Analysis78## When to use this skill910Use when measuring **sequential step-by-step conversion** through a defined flow. Triggers:1112- "Build a signup funnel"13- "Where are users dropping off?"14- "Conversion from step A to step B"15- "Analyze the checkout flow"16- "Activation funnel"1718For lifecycle behavior over weeks/months → `cohort-analysis`. For experiments → `ab-test-analysis`.1920## Required inputs2122| Input | Why it matters |23|---|---|24| Funnel steps (ordered) | The sequence to measure |25| Unit of analysis | User, session, or visit |26| Time window | Conversion deadline between steps |27| Strict vs non-strict order | Must steps occur in order, or just all eventually? |28| Cohort filter | Which users to include (e.g., new signups only) |2930## Workflow31321. **Define the steps explicitly.** Each step is an event name + filter conditions. Avoid vague steps like "engaged."33342. **Decide strict vs non-strict ordering.**35 - **Strict (sequential)**: step N must follow step N-1 in time. Standard for onboarding/checkout flows.36 - **Non-strict (any order)**: user must have done all steps eventually. Use for feature adoption funnels where order doesn't matter.37383. **Set the conversion window.** Between step N and N+1, what's the max time to convert? Common defaults:39 - Same session: ~30 min40 - Same day: 24h41 - Same week: 7 days42 - Lifetime: open-ended (but inflates conversion artificially)43444. **Compute the funnel using `scripts/build_funnel.sql`**, which produces:45 - Step counts (users reaching each step)46 - Step-to-step conversion rate47 - End-to-end conversion rate48 - Median time between steps49505. **Diagnose biggest drop-offs.** The largest absolute drop is usually the highest-leverage fix. Compare:51 - vs benchmark (industry, prior period)52 - vs segments (channel, device, plan)53546. **Segment to find the right bucket.** Compare the funnel by:55 - Acquisition channel56 - Device (mobile vs desktop)57 - User type (new vs returning)58 - Country / locale5960 Look for steps where conversion **diverges** between segments. These are the actionable insights.61627. **Generate the three canonical visualizations** using `scripts/visualize_funnel.py`:63 - **Waterfall chart** — users at each step with cumulative loss overlay (end-to-end view)64 - **Step-to-step bar chart** — per-transition conversion rate, color-coded by health65 - **Monthly cohort heatmap** — cohort × step conversion %, to see if the funnel is improving or degrading over time6667 When responding inline (no PNG output), produce equivalent markdown tables for each — see `reference.md` for the inline templates.68698. **Write the readout.**7071## Output format7273```markdown74# Funnel Analysis: <name>7576## Definitions77- Unit: <user | session>78- Cohort filter: <e.g., new signups in last 14 days>79- Ordering: <strict | non-strict>80- Conversion window: <e.g., same session, max 30 min between steps>81- Date range: <start> to <end>8283## Funnel (overall)84| Step | Users | Step CR | End-to-end CR | Median time from prev |85|---|---|---|---|---|86| 1. Landing | 100,000 | — | 100% | — |87| 2. Signup | 32,000 | 32.0% | 32.0% | 1.2 min |88| 3. Email verify | 22,400 | 70.0% | 22.4% | 4.5 min |89| 4. Profile complete | 16,800 | 75.0% | 16.8% | 2.1 min |90| 5. First action | 10,080 | 60.0% | 10.1% | 14 min |9192## Visualizations9394### Waterfall — end-to-end conversion from step 1959697Bars show users at each step; gray overlays show users lost since the previous step. Headline: 10.1% end-to-end conversion (step 1 → final).9899### Step-to-step conversion100101102Each bar is the conversion rate from step N to step N+1 (green ≥80%, amber ≥50%, red <50%). Worst transition flagged in the diagnosis below.103104### Monthly cohort heatmap105106107Rows = signup month, columns = funnel step, cell = % of that cohort reaching the step. Reveals whether the funnel is trending up, flat, or degrading across cohorts.108109## Biggest drop-offs1101. **Landing → Signup**: -68pp drop (32% conversion). Largest absolute loss.1112. **Profile complete → First action**: -40pp drop, slowest median time (14 min) — suggests confusion or friction.112113## Segment breakdowns114| Segment | Landing→Signup | Signup→Verify | Verify→Profile | Profile→First |115|---|---|---|---|---|116| Mobile | 28% | 65% | 73% | 52% |117| Desktop | 38% | 78% | 78% | 68% |118| Paid search | 35% | 72% | 76% | 64% |119| Organic | 24% | 68% | 73% | 55% |120121**Key finding:** Mobile users underperform desktop at every step. Largest mobile gap is at "first action" (52% vs 68%) — suggests post-signup mobile experience friction.122123## Interpretation124- The single biggest leverage point is landing → signup (-68pp). Even a 2pp improvement = 2,000 more weekly signups.125- However, the most actionable opportunity is **mobile first-action** because the gap vs desktop is large and the cohort is high-intent (already signed up).126127## Caveats128- "First action" definition: <event spec>129- Users counted at most once per step (deduplicated by user_id)130- Mobile = iOS + Android combined; gap may differ by OS131132## Next steps133- Run heatmap analysis on mobile post-signup screens134- Pre-register an A/B test on the signup form (see `ab-test-design`)135```136137## Validation checks138139- [ ] Each step has a single, unambiguous event definition140- [ ] Conversion window stated and consistent141- [ ] Deduplication rule stated (1 user = 1 row per step)142- [ ] Date range stated and excludes incomplete most-recent day143- [ ] Step counts monotonically non-increasing in strict funnels144145## Edge cases & failure modes146147- **Skipped steps**: in non-strict funnels, a user might skip step 3 and do step 4. Decide if they "count" for step 3. Default: no, they don't.148- **Re-entries**: user does step 1, abandons, comes back next day and does step 1 again. Count first instance only (use min event timestamp).149- **Lifetime windows inflate conversion**: a 30-day window will show higher conversion than 1-day, but the trailing days are mostly "users who eventually got around to it" rather than directly attributable to the funnel design.150- **Survivorship at later steps**: late steps have small N — small absolute changes look like big percentage shifts. Show absolute counts alongside rates.151- **Step granularity**: too granular (10+ steps) makes drop-off diagnosis impossible. Roll up. 4-6 steps is the sweet spot.152153## Scripts154155- `scripts/build_funnel.sql` — Snowflake template for strict-ordered funnel with time-bounded steps.156- `scripts/visualize_funnel.py` — Produces the three canonical PNGs (waterfall, step-to-step, cohort heatmap) from a long-format events CSV.157158```bash159python scripts/visualize_funnel.py \160 --input events.csv \161 --steps landing,signup,email_verify,profile_complete,first_action \162 --output-dir charts/ \163 --cohort-grain month \164 --strict165```166167## Related skills168169- `cohort-analysis` — for lifecycle behavior over weeks/months170- `metric-definition` — pin down each step's event definition171- `ab-test-design` — test a fix to the biggest drop-off172- `data-quality-audit` — sanity-check the event sources before trusting the funnel