North Star Command Center Ad Intelligence L3 Deep Dive Capital Efficiency Personas Placements Widget Localization

Widget Retention

Cohort retention curves · Filter by widget type, month, age, premium
Generated: May 30, 2026 14:41
Cohort Month
Platform
Widget Type
Placement
Age
Onboarding
Premium
Retention Curves All Time
Widget Activation by Age Who activates widgets?

Activation Rate by Age

Breakdowns By Age & Premium

Retention by Age (selected cohort type)

Retention — Premium vs Free

First-Week L3 by Group 3+ days in first week, widget screens excluded
L3 Curves 3+ real-screen days per week
L3 Breakdowns By Age & Premium

L3 by Age

L3 — Premium vs Free

ℹ️ Methodology & Data Sources

What This Dashboard Measures

This dashboard tracks how widget activation (setting up a Bible verse widget on the home/lock screen) affects retention (coming back to the app) and L3 (using the app 3+ days per week). All data is US-only.

Cohort Definitions

Every widget user is assigned to exactly one cohort type based on their behavior:

CohortDefinitionPlatform
iOS ScratchSet a widget AND scratched it within ±7 daysiOS only
iOS No ScratchSet a widget, never scratchediOS only
iOS Later ScratchedSet a widget, scratched it later (outside ±7 day window)iOS only
Android WidgetSet any widgetAndroid
Baseline iOS / AndroidNever set a widgetBoth

Scratch = the interactive widget where users physically scratch to reveal a verse. Time-based: a user who scratched within 7 days before or after setting the widget counts as “scratch.”

Cohort week = the Monday-start week when the user first set their widget. All week numbers (W1, W2, etc.) are relative to this date.

How Cohorts Are Built (Technical Detail)

Step 1: Identify Widget Setters

Source: northstar.widget_events_1y — all GA4 widget events for US users in the last year.

iOS set events: did_set_daily_verse_widget → daily_verse, did_set_hourly_verse_widget → hourly_verse
Android set events: widget_daily_verse_small_set, widget_daily_verse_large_set → daily_verse; widget_hourly_verse_small_set, widget_hourly_verse_large_set → hourly_verse
Scratch event: widget_scratched (iOS only)

For each user × widget_type combination, we take MIN(event_date) as their first_widget_date.

Step 2: Classify Scratch Behavior

Find each user’s first scratch date, then classify based on the time gap between widget set and first scratch:

  • ios_scratch: Scratched within ±7 days of setting widget
  • ios_later_scratched: Scratched, but outside the ±7 day window
  • ios_pure_no_scratch: iOS, set widget, never scratched
  • android_verse: Android (no scratch feature)

Why ±7 days? Scratch happening near the widget set date indicates early engagement with the interactive feature. Later scratchers found it organically — a separate “power user” cohort.

Mutually exclusive — each user appears in exactly one type (verified: only 709 of 3.3M users, 0.02%, edge cases).

Step 3: Assign Placement

Source: widget_family field in widget set events:

  • accessoryRectangularlock screen
  • systemMedium / systemLargehome screen

Classification per user (mutually exclusive): home_only, lock_only, both, unknown (older events, Android).

Step 4: Assign Demographics

  • Age: From sandbox_analytics.users.age — 13-17, 18-24, 25-34, 35-44, 45-54, 55+, unknown
  • Premium status: User has ANY Adapty event in bc-ads-tester.subscription.adapty_realtime. Lifetime flag.
  • Onboarding passed: User exists in data_warehouse.onboarding_passed (16.8M users, full history since 2023).
  • Platform: From northstar.user_platform_lookup. Normalized to iOS/Android in activation tables.

Step 5: Cohort Week & Baseline

Widget users: cohort_week = DATE_TRUNC(first_widget_date, WEEK(MONDAY))

Baseline users: US users from sandbox_analytics.users who never appear in widget_events_1y. Cohort week = account creation week. Baseline starts April 7, 2025.

How Retention Is Counted

For each cohort user, check if they had any screen activity in week N after their cohort_week. Source: northstar.user_daily_activity (126M rows, full history). Incremental daily updates from user_daily_screens.

How L3 Is Counted

Same as retention but higher bar: 3+ distinct days with real screen activity in the week. “Real screen” = unique_screens > 1 OR screens_visited[0] != 'splash_screen'. Excludes splash-only sessions (37% of daily entries). Uses DELETE+INSERT for the current week (L3 status changes as the week accumulates).

How Widget Entry Is Counted

Users who came back specifically by tapping the widget (deeplink entry). Identified via data_warehouse.deeplink_open: deeplink_source = 'pre_widget' AND deeplink_type = 'splash' AND deepLink contains "type":"daily" or "type":"hourly". iOS only.

NOT deeplink_source = 'widget' — that’s the panic button / affirmation widget.

Population Summary (April 15, 2026)

GroupUsers% Passed Onboarding
iOS Scratch~172K~95%
iOS No Scratch~2.4M~78%
iOS Later Scratched~58K~93%
Android Widget~280K~72%
Baseline iOS~2.1M (ob passed)48% of total
Baseline Android~550K (ob passed)45% of total

Widget Types & Placement

  • Daily Verse / Hourly Verse — the two widget types. A user can have both; in widget_cohort_sizes, they appear as separate rows per type.
  • Placement: Home Only, Lock Only, or Both — mutually exclusive per user. Determined by the widget_family field: accessoryRectangular = lock screen, systemMedium/systemLarge = home screen.

Retention (How It’s Calculated)

Definition: A user is “retained” in week N if they had any screen activity in that week (including splash screen).

Formula: retention_rate = active_users / cohort_size × 100

Week numbering: W1 = first full week after widget set (or install for baseline). W0 = the install/widget-set week itself (partial).

L3 (How It’s Calculated)

Definition: A user is “L3” in week N if they visited 3 or more distinct days with real screen activity in that week.

“Real screen activity” = the user visited at least one screen beyond just splash_screen. This is critical because 37% of daily “active” entries are splash-only — a user tapped their widget, saw the splash screen, and closed the app without actually using it. These ghost sessions are excluded from L3 but included in retention.

Formula: l3_rate = l3_users / cohort_size × 100

Key difference from retention: Retention = any activity (low bar). L3 = 3+ real-screen days (high bar). L3 is the North Star metric.

Entry Retention & Entry L3

Definition: Measures users who returned to the app specifically via tapping the widget (deeplink entry), not through any other path.

How we identify widget entries: deeplink_source = 'pre_widget' AND deeplink_type = 'splash' AND the deepLink JSON contains "type":"daily" or "type":"hourly".

iOS only — deeplink tracking data is only available for iOS.

NOT deeplink_source = 'widget' — that’s the panic button / affirmation widget, a different feature.

Onboarding Passed Filter

Default: ON (showing only users who completed onboarding).

Why it matters: Without this filter, the baseline includes users who bounced during onboarding and never entered the app. This makes widget lift look artificially high. With the filter on:

  • Baseline W1 retention: ~34% (post-onboarding) vs ~18% (all users)
  • This gives a fair apples-to-apples comparison

Toggle to “All” to see the unfiltered view including onboarding bouncers.

Widget Activation by Age

Definition: What percentage of new US users in each age group set up a widget.

Source: northstar.widget_activation_by_age — a materialized table with COUNT(DISTINCT user_id) for both numerator (widget setters) and denominator (all new users). No double-counting possible.

Pie chart: Distribution — what share of widget activators are in each age group.
Bar chart: Rate — what % of new users in each age group activate.

Data Pipeline

Time (UTC)What
~06:00GA4 daily export — raw events available
07:00data_warehouse pipelines — screens, deeplink_open, onboarding_passed
07:00sandbox_analytics refresh — user_daily_screens, users
08:00northstar_daily_refresh — L3 smiling curves, placements
09:00widget_daily_refresh — all tables on this dashboard

Dashboard refresh: Hourly via GitHub Actions → Cloudflare Pages

Premium Status

A user is “premium” if they have ANY of these Adapty events: trial_started, trial_converted, subscription_started, subscription_renewed. This is a lifetime flag — once premium, always premium in this data.

Data Quality Notes

  • widget_type overlap: A user with both daily + hourly verse appears in both widget_type rows in widget_cohort_sizes. Summing across widget_types inflates by ~10%. The activation table uses DISTINCT user_id to avoid this.
  • Current week L3 is incomplete — accumulates Mon→Sun, recomputed daily. The dashboard cuts off the latest partial week.
  • Android has no entry data — deeplink tracking is iOS only.

Tables Used

TableRowsWhat
widget_cohort_sizes18KDenominators for all widget curves
baseline_cohort_sizes3.3KDenominators for baseline curves
widget_retention369KWeekly retention (any activity)
baseline_retention70KBaseline weekly retention
widget_entry_retention141KRetention via widget tap (iOS)
widget_l3_curves369KWeekly L3 (3+ real-screen days)
baseline_l3_curves70KBaseline weekly L3
widget_entry_l3141KL3 via widget tap (iOS)
widget_activation_by_age~2KClean activation rates by age
user_daily_activity126MDaily screen activity with splash flag

Last updated: April 15, 2026