Funnel analysis example
with mobile app event data.
Three labeled event logs, the funnel chart each one produces and how every step is counted.
How every example is counted
- The cohort is the unique devices whose first_open falls inside the date range.
- Each stage is the unique cohort devices that sent its event inside the same range.
- There is no sequence or time-window check, so a device that skips a step still counts at the stages it reached.
- Step conversion divides a stage by the one before it and can pass 100%. Events without a device id are ignored.
Every device, user and timestamp is synthetic. The counts come from the same engine as the dashboard, as described in the events docs.
Conversion funnel analysis example: onboarding to purchase
Synthetic data 20 installs in one week, four onboarding steps, then the paywall. Each stage loses a similar share, except the paywall.
| Step | Users | Step conversion | Overall | Lost | |
|---|---|---|---|---|---|
| Installed | 20 | 100% | |||
| Step 0: goal | 18 | 90% | 90% | 2 | |
| Step 1: experience level | 16 | 88.9% | 80% | 2 | |
| Step 2: weekly schedule | 14 | 87.5% | 70% | 2 | |
| Step 3: notifications | 12 | 85.7% | 60% | 2 | |
| Completed | 11 | 91.7% | 55% | 1 | |
| Paywall shown | 11 | 100% | 55% | 0 | |
| Plan selected | 5 | 45.5% | 25% | 6 | |
| Purchased | 2 | 40% | 10% | 3 |
- Every onboarding stage keeps 86 to 92% of the one before, so no single step stands out.
- 11 of 11 devices that finish onboarding see the paywall.
- Only 5 of those 11 pick a plan, the largest loss in the funnel.
Event log (111 events)
| Time (UTC) | Device | User | Event | Props |
|---|---|---|---|---|
| 09-07 01:00 | d_a01 | u_a01 | first_open | |
| 09-07 01:03 | d_a01 | u_a01 | onboarding_step | {"index":0,"id":"goal"} |
| 09-07 01:06 | d_a01 | u_a01 | onboarding_step | {"index":1,"id":"experience level"} |
| 09-07 01:09 | d_a01 | u_a01 | onboarding_step | {"index":2,"id":"weekly schedule"} |
| 09-07 01:12 | d_a01 | u_a01 | onboarding_step | {"index":3,"id":"notifications"} |
| 09-07 01:15 | d_a01 | u_a01 | onboarding_completed | |
| 09-07 01:18 | d_a01 | u_a01 | paywall_shown | {"placement":"onboarding"} |
| 09-07 01:21 | d_a01 | u_a01 | paywall_plan_selected | {"plan":"monthly"} |
| 09-07 01:24 | d_a01 | u_a01 | paywall_purchased | {"plan":"monthly"} |
| 09-07 09:00 | d_a02 | u_a02 | first_open | |
| 09-07 09:03 | d_a02 | u_a02 | onboarding_step | {"index":0,"id":"goal"} |
| 09-07 09:06 | d_a02 | u_a02 | onboarding_step | {"index":1,"id":"experience level"} |
| 09-07 09:09 | d_a02 | u_a02 | onboarding_step | {"index":2,"id":"weekly schedule"} |
| 09-07 09:12 | d_a02 | u_a02 | onboarding_step | {"index":3,"id":"notifications"} |
| 09-07 09:15 | d_a02 | u_a02 | onboarding_completed | |
| 09-07 09:18 | d_a02 | u_a02 | paywall_shown | {"placement":"onboarding"} |
| 09-07 09:21 | d_a02 | u_a02 | paywall_plan_selected | {"plan":"monthly"} |
| 09-07 09:24 | d_a02 | u_a02 | paywall_purchased | {"plan":"lifetime"} |
| 09-07 17:00 | d_a03 | u_a03 | first_open | |
| 09-07 17:03 | d_a03 | u_a03 | onboarding_step | {"index":0,"id":"goal"} |
| 09-07 17:06 | d_a03 | u_a03 | onboarding_step | {"index":1,"id":"experience level"} |
| 09-07 17:09 | d_a03 | u_a03 | onboarding_step | {"index":2,"id":"weekly schedule"} |
| 09-07 17:12 | d_a03 | u_a03 | onboarding_step | {"index":3,"id":"notifications"} |
| 09-07 17:15 | d_a03 | u_a03 | onboarding_completed | |
| 09-07 17:18 | d_a03 | u_a03 | paywall_shown | {"placement":"onboarding"} |
| 09-07 17:21 | d_a03 | u_a03 | paywall_plan_selected | {"plan":"monthly"} |
| 09-08 01:00 | d_a04 | u_a04 | first_open | |
| 09-08 01:03 | d_a04 | u_a04 | onboarding_step | {"index":0,"id":"goal"} |
| 09-08 01:06 | d_a04 | u_a04 | onboarding_step | {"index":1,"id":"experience level"} |
| 09-08 01:09 | d_a04 | u_a04 | onboarding_step | {"index":2,"id":"weekly schedule"} |
| 09-08 01:12 | d_a04 | u_a04 | onboarding_step | {"index":3,"id":"notifications"} |
| 09-08 01:15 | d_a04 | u_a04 | onboarding_completed | |
| 09-08 01:18 | d_a04 | u_a04 | paywall_shown | {"placement":"onboarding"} |
| 09-08 01:21 | d_a04 | u_a04 | paywall_plan_selected | {"plan":"monthly"} |
| 09-08 09:00 | d_a05 | u_a05 | first_open | |
| 09-08 09:03 | d_a05 | u_a05 | onboarding_step | {"index":0,"id":"goal"} |
| 09-08 09:06 | d_a05 | u_a05 | onboarding_step | {"index":1,"id":"experience level"} |
| 09-08 09:09 | d_a05 | u_a05 | onboarding_step | {"index":2,"id":"weekly schedule"} |
| 09-08 09:12 | d_a05 | u_a05 | onboarding_step | {"index":3,"id":"notifications"} |
| 09-08 09:15 | d_a05 | u_a05 | onboarding_completed | |
| 09-08 09:18 | d_a05 | u_a05 | paywall_shown | {"placement":"onboarding"} |
| 09-08 09:21 | d_a05 | u_a05 | paywall_plan_selected | {"plan":"lifetime"} |
| 09-08 17:00 | d_a06 | u_a06 | first_open | |
| 09-08 17:03 | d_a06 | u_a06 | onboarding_step | {"index":0,"id":"goal"} |
| 09-08 17:06 | d_a06 | u_a06 | onboarding_step | {"index":1,"id":"experience level"} |
| 09-08 17:09 | d_a06 | u_a06 | onboarding_step | {"index":2,"id":"weekly schedule"} |
| 09-08 17:12 | d_a06 | u_a06 | onboarding_step | {"index":3,"id":"notifications"} |
| 09-08 17:15 | d_a06 | u_a06 | onboarding_completed | |
| 09-08 17:18 | d_a06 | u_a06 | paywall_shown | {"placement":"onboarding"} |
| 09-09 01:00 | d_a07 | u_a07 | first_open | |
| 09-09 01:03 | d_a07 | u_a07 | onboarding_step | {"index":0,"id":"goal"} |
| 09-09 01:06 | d_a07 | u_a07 | onboarding_step | {"index":1,"id":"experience level"} |
| 09-09 01:09 | d_a07 | u_a07 | onboarding_step | {"index":2,"id":"weekly schedule"} |
| 09-09 01:12 | d_a07 | u_a07 | onboarding_step | {"index":3,"id":"notifications"} |
| 09-09 01:15 | d_a07 | u_a07 | onboarding_completed | |
| 09-09 01:18 | d_a07 | u_a07 | paywall_shown | {"placement":"onboarding"} |
| 09-09 01:21 | d_a07 | u_a07 | paywall_dismissed | |
| 09-09 09:00 | d_a08 | u_a08 | first_open | |
| 09-09 09:03 | d_a08 | u_a08 | onboarding_step | {"index":0,"id":"goal"} |
| 09-09 09:06 | d_a08 | u_a08 | onboarding_step | {"index":1,"id":"experience level"} |
| 09-09 09:09 | d_a08 | u_a08 | onboarding_step | {"index":2,"id":"weekly schedule"} |
| 09-09 09:12 | d_a08 | u_a08 | onboarding_step | {"index":3,"id":"notifications"} |
| 09-09 09:15 | d_a08 | u_a08 | onboarding_completed | |
| 09-09 09:18 | d_a08 | u_a08 | paywall_shown | {"placement":"onboarding"} |
| 09-09 17:00 | d_a09 | u_a09 | first_open | |
| 09-09 17:03 | d_a09 | u_a09 | onboarding_step | {"index":0,"id":"goal"} |
| 09-09 17:06 | d_a09 | u_a09 | onboarding_step | {"index":1,"id":"experience level"} |
| 09-09 17:09 | d_a09 | u_a09 | onboarding_step | {"index":2,"id":"weekly schedule"} |
| 09-09 17:12 | d_a09 | u_a09 | onboarding_step | {"index":3,"id":"notifications"} |
| 09-09 17:15 | d_a09 | u_a09 | onboarding_completed | |
| 09-09 17:18 | d_a09 | u_a09 | paywall_shown | {"placement":"onboarding"} |
| 09-09 17:21 | d_a09 | u_a09 | paywall_dismissed | |
| 09-10 01:00 | d_a10 | u_a10 | first_open | |
| 09-10 01:03 | d_a10 | u_a10 | onboarding_step | {"index":0,"id":"goal"} |
| 09-10 01:06 | d_a10 | u_a10 | onboarding_step | {"index":1,"id":"experience level"} |
| 09-10 01:09 | d_a10 | u_a10 | onboarding_step | {"index":2,"id":"weekly schedule"} |
| 09-10 01:12 | d_a10 | u_a10 | onboarding_step | {"index":3,"id":"notifications"} |
| 09-10 01:15 | d_a10 | u_a10 | onboarding_completed | |
| 09-10 01:18 | d_a10 | u_a10 | paywall_shown | {"placement":"onboarding"} |
| 09-10 09:00 | d_a11 | u_a11 | first_open | |
| 09-10 09:03 | d_a11 | u_a11 | onboarding_step | {"index":0,"id":"goal"} |
| 09-10 09:06 | d_a11 | u_a11 | onboarding_step | {"index":1,"id":"experience level"} |
| 09-10 09:09 | d_a11 | u_a11 | onboarding_step | {"index":2,"id":"weekly schedule"} |
| 09-10 09:12 | d_a11 | u_a11 | onboarding_step | {"index":3,"id":"notifications"} |
| 09-10 09:15 | d_a11 | u_a11 | onboarding_completed | |
| 09-10 09:18 | d_a11 | u_a11 | paywall_shown | {"placement":"onboarding"} |
| 09-10 17:00 | d_a12 | u_a12 | first_open | |
| 09-10 17:03 | d_a12 | u_a12 | onboarding_step | {"index":0,"id":"goal"} |
| 09-10 17:06 | d_a12 | u_a12 | onboarding_step | {"index":1,"id":"experience level"} |
| 09-10 17:09 | d_a12 | u_a12 | onboarding_step | {"index":2,"id":"weekly schedule"} |
| 09-10 17:12 | d_a12 | u_a12 | onboarding_step | {"index":3,"id":"notifications"} |
| 09-11 01:00 | d_a13 | u_a13 | first_open | |
| 09-11 01:03 | d_a13 | u_a13 | onboarding_step | {"index":0,"id":"goal"} |
| 09-11 01:06 | d_a13 | u_a13 | onboarding_step | {"index":1,"id":"experience level"} |
| 09-11 01:09 | d_a13 | u_a13 | onboarding_step | {"index":2,"id":"weekly schedule"} |
| 09-11 09:00 | d_a14 | u_a14 | first_open | |
| 09-11 09:03 | d_a14 | u_a14 | onboarding_step | {"index":0,"id":"goal"} |
| 09-11 09:06 | d_a14 | u_a14 | onboarding_step | {"index":1,"id":"experience level"} |
| 09-11 09:09 | d_a14 | u_a14 | onboarding_step | {"index":2,"id":"weekly schedule"} |
| 09-11 17:00 | d_a15 | u_a15 | first_open | |
| 09-11 17:03 | d_a15 | u_a15 | onboarding_step | {"index":0,"id":"goal"} |
| 09-11 17:06 | d_a15 | u_a15 | onboarding_step | {"index":1,"id":"experience level"} |
| 09-12 01:00 | d_a16 | u_a16 | first_open | |
| 09-12 01:03 | d_a16 | u_a16 | onboarding_step | {"index":0,"id":"goal"} |
| 09-12 01:06 | d_a16 | u_a16 | onboarding_step | {"index":1,"id":"experience level"} |
| 09-12 09:00 | d_a17 | u_a17 | first_open | |
| 09-12 09:03 | d_a17 | u_a17 | onboarding_step | {"index":0,"id":"goal"} |
| 09-12 17:00 | d_a18 | u_a18 | first_open | |
| 09-12 17:03 | d_a18 | u_a18 | onboarding_step | {"index":0,"id":"goal"} |
| 09-13 01:00 | d_a19 | u_a19 | first_open | |
| 09-13 09:00 | d_a20 | u_a20 | first_open |
Funnel analysis example with skipped steps and incomplete journeys
Synthetic data 14 installs where people skip steps, stop early or buy without a completed event. A stage can end up larger than the one before it.
| Step | Users | Step conversion | Overall | Lost | |
|---|---|---|---|---|---|
| Installed | 14 | 100% | |||
| Step 0: goal | 9 | 64.3% | 64% | 5 | |
| Step 1: experience level | 6 | 66.7% | 43% | 3 | |
| Step 2: weekly schedule | 7 | 116.7% | 50% | 0 | |
| Step 3: notifications | 6 | 85.7% | 43% | 1 | |
| Completed | 6 | 100% | 43% | 0 | |
| Paywall shown | 8 | 133.3% | 57% | 0 | |
| Plan selected | 5 | 62.5% | 36% | 3 | |
| Purchased | 3 | 60% | 21% | 2 |
- Device 05 skips step 1 and device 10 skips steps 1 and 3, so step 2 has more devices than step 1.
- Devices 09 and 10 reach the paywall without a completed event, so the paywall has more devices than completed.
- Device 08's purchase is dated after the week ends, and one purchase has a user id but no device id. Neither is counted.
Event log (70 events)
| Time (UTC) | Device | User | Event | Props |
|---|---|---|---|---|
| 09-07 01:00 | d_c01 | u_c01 | first_open | |
| 09-07 01:03 | d_c01 | u_c01 | onboarding_step | {"index":0,"id":"goal"} |
| 09-07 01:06 | d_c01 | u_c01 | onboarding_step | {"index":1,"id":"experience level"} |
| 09-07 01:09 | d_c01 | u_c01 | onboarding_step | {"index":2,"id":"weekly schedule"} |
| 09-07 01:12 | d_c01 | u_c01 | onboarding_step | {"index":3,"id":"notifications"} |
| 09-07 01:15 | d_c01 | u_c01 | onboarding_completed | |
| 09-07 01:18 | d_c01 | u_c01 | paywall_shown | {"placement":"onboarding"} |
| 09-07 01:21 | d_c01 | u_c01 | paywall_plan_selected | {"plan":"monthly"} |
| 09-07 01:24 | d_c01 | u_c01 | paywall_purchased | {"plan":"monthly"} |
| 09-07 12:40 | d_c02 | u_c02 | first_open | |
| 09-07 12:43 | d_c02 | u_c02 | onboarding_step | {"index":0,"id":"goal"} |
| 09-07 12:46 | d_c02 | u_c02 | onboarding_step | {"index":1,"id":"experience level"} |
| 09-07 12:49 | d_c02 | u_c02 | onboarding_step | {"index":2,"id":"weekly schedule"} |
| 09-07 12:52 | d_c02 | u_c02 | onboarding_step | {"index":3,"id":"notifications"} |
| 09-07 12:55 | d_c02 | u_c02 | onboarding_completed | |
| 09-07 12:58 | d_c02 | u_c02 | paywall_shown | {"placement":"onboarding"} |
| 09-07 13:01 | d_c02 | u_c02 | paywall_plan_selected | {"plan":"lifetime"} |
| 09-08 00:20 | d_c03 | u_c03 | first_open | |
| 09-08 00:23 | d_c03 | u_c03 | onboarding_step | {"index":0,"id":"goal"} |
| 09-08 00:26 | d_c03 | u_c03 | onboarding_step | {"index":1,"id":"experience level"} |
| 09-08 00:29 | d_c03 | u_c03 | onboarding_step | {"index":2,"id":"weekly schedule"} |
| 09-08 00:32 | d_c03 | u_c03 | onboarding_step | {"index":3,"id":"notifications"} |
| 09-08 00:35 | d_c03 | u_c03 | onboarding_completed | |
| 09-08 00:38 | d_c03 | u_c03 | paywall_shown | {"placement":"onboarding"} |
| 09-08 00:41 | d_c03 | u_c03 | paywall_dismissed | |
| 09-08 12:00 | d_c04 | u_c04 | first_open | |
| 09-08 12:03 | d_c04 | u_c04 | onboarding_step | {"index":0,"id":"goal"} |
| 09-08 12:06 | d_c04 | u_c04 | onboarding_step | {"index":1,"id":"experience level"} |
| 09-08 12:09 | d_c04 | u_c04 | onboarding_step | {"index":2,"id":"weekly schedule"} |
| 09-08 12:12 | d_c04 | u_c04 | onboarding_step | {"index":3,"id":"notifications"} |
| 09-08 12:15 | d_c04 | u_c04 | onboarding_completed | |
| 09-08 12:18 | d_c04 | u_c04 | paywall_shown | {"placement":"onboarding"} |
| 09-08 12:21 | d_c04 | u_c04 | paywall_dismissed | |
| 09-08 23:40 | d_c05 | u_c05 | first_open | |
| 09-08 23:43 | d_c05 | u_c05 | onboarding_step | {"index":0,"id":"goal"} |
| 09-08 23:46 | d_c05 | u_c05 | onboarding_step | {"index":2,"id":"weekly schedule"} |
| 09-08 23:49 | d_c05 | u_c05 | onboarding_step | {"index":3,"id":"notifications"} |
| 09-08 23:52 | d_c05 | u_c05 | onboarding_completed | |
| 09-08 23:55 | d_c05 | u_c05 | paywall_shown | {"placement":"onboarding"} |
| 09-08 23:58 | d_c05 | u_c05 | paywall_plan_selected | {"plan":"monthly"} |
| 09-09 00:01 | d_c05 | u_c05 | paywall_purchased | {"plan":"monthly"} |
| 09-09 11:20 | d_c06 | u_c06 | first_open | |
| 09-09 11:23 | d_c06 | u_c06 | onboarding_step | {"index":0,"id":"goal"} |
| 09-09 11:26 | d_c06 | u_c06 | onboarding_step | {"index":1,"id":"experience level"} |
| 09-09 23:00 | d_c07 | u_c07 | first_open | |
| 09-09 23:03 | d_c07 | u_c07 | onboarding_step | {"index":0,"id":"goal"} |
| 09-10 10:40 | d_c08 | u_c08 | first_open | |
| 09-10 10:43 | d_c08 | u_c08 | onboarding_step | {"index":0,"id":"goal"} |
| 09-10 10:46 | d_c08 | u_c08 | onboarding_step | {"index":1,"id":"experience level"} |
| 09-10 10:49 | d_c08 | u_c08 | onboarding_step | {"index":2,"id":"weekly schedule"} |
| 09-10 10:52 | d_c08 | u_c08 | onboarding_step | {"index":3,"id":"notifications"} |
| 09-10 10:55 | d_c08 | u_c08 | onboarding_completed | |
| 09-10 10:58 | d_c08 | u_c08 | paywall_shown | {"placement":"onboarding"} |
| 09-10 11:01 | d_c08 | u_c08 | paywall_plan_selected | {"plan":"monthly"} |
| 09-10 22:20 | d_c09 | u_c09 | first_open | |
| 09-10 22:23 | d_c09 | u_c09 | paywall_shown | {"placement":"onboarding"} |
| 09-11 10:00 | d_c10 | u_c10 | first_open | |
| 09-11 10:03 | d_c10 | u_c10 | onboarding_step | {"index":0,"id":"goal"} |
| 09-11 10:06 | d_c10 | u_c10 | onboarding_step | {"index":2,"id":"weekly schedule"} |
| 09-11 10:09 | d_c10 | u_c10 | paywall_shown | {"placement":"onboarding"} |
| 09-11 10:12 | d_c10 | u_c10 | paywall_plan_selected | {"plan":"lifetime"} |
| 09-11 10:15 | d_c10 | u_c10 | paywall_purchased | {"plan":"lifetime"} |
| 09-11 21:40 | d_c11 | u_c11 | first_open | |
| 09-12 09:20 | d_c12 | u_c12 | first_open | |
| 09-12 21:00 | d_c13 | u_c13 | first_open | |
| 09-12 21:03 | d_c13 | u_c13 | app_open | |
| 09-12 21:06 | d_c13 | u_c13 | workout_logged | {"type":"run"} |
| 09-13 08:40 | d_c14 | u_c14 | first_open | |
| 09-13 09:20 | none | u_c99 | paywall_purchased | {"plan":"monthly"} |
| 09-14 05:00 | d_c08 | u_c08 | paywall_purchased | {"plan":"monthly"} |
Funnel analysis example FAQ
How do you do a funnel analysis on app events?
Pick the ordered events, set the install cohort and the date range, then count the unique devices at each step. Divide each count by the step before it for step conversion and by installs for overall conversion. To try it with typed numbers, use the funnel calculator.
What does a funnel analysis chart show?
One bar per step, sized by its share of installs, with the step conversion and the users lost beside it. The step with the largest loss is the leak to fix first. See onboarding funnel analytics for the same chart on live events.
How does ActivationPal count repeated and skipped steps?
It counts unique devices per stage and does not check the order. A device that jumps to the paywall counts at the paywall, so a stage can be larger than the one before it, as in the third example. The event names are in the events docs and the setup is in the quickstart.
More free tools
- App Store account auditPortfolio similarity, review signals and listing concerns, with evidence.Open →
- App revenue calculator12 months of subscription revenue from installs, conversion and price.Open →
- Funnel calculatorStep conversion, drop-off and a chart from the users at each step.Open →
- App revenue by countryWorked country revenue datasets on labeled synthetic data, with shares and tier rollups.Open →
- ARPU calculatorGross and net average revenue per user from revenue and users.Open →
- Cohort analysis toolA retention heatmap from weekly cohort sizes and users still active.Open →
- App Store keyword checkerPopularity and difficulty for any keyword, in any country.Open →
- Country pricing tiersEvery country in five pricing tiers, with the discount for each.Open →