offdataai
SaaS & Technology · data model template

SaaS Product-Led Growth & Retention Cohort Analytics data model

Kimball warehouse for SaaS PLG: four facts (signup-activation accumulating snapshot, ARR-movement event, monthly MRR/ARR periodic snapshot, daily product-usage periodic snapshot) over conformed date, month, user (SCD2), account (SCD2), plan, acquisition channel, movement type, customer segment, and feature dimensions. Drives NRR by signup cohort, GRR, ARR waterfall, activation rate, time-to-value, and feature adoption reports.

SaaS product-led growth analytics — signup → activation → expansion → retention funnel modelled as a Kimball mart on Snowflake. Cohorts anchored on signup month flow into monthly MRR/ARR composition snapshots, ARR movement events (new / expansion / contraction / churn / reactivation) for the ARR waterfall, and daily product-usage facts feeding adoption depth and customer-health scoring. SCD2 account and user dimensions preserve as-was segment, plan, and CSM assignment for comparable NRR / GRR / logo-retention reporting; a plan role-play on the movement fact captures upgrade / downgrade direction. It is a Kimball dimensional model: fact tables at a declared grain surrounded by conformed dimensions, ready for BI tools and a semantic layer.

KimballSaaS & TechnologySOC2GDPR
13
tables
124
columns
19
relationships
1
PII columns

Opening the template creates a project with the ERD, platform-native DDL, a dbt project and documentation already generated (recommended platform: Snowflake). Edit it in plain English or on the canvas, then ship it to any supported warehouse.

Subject areas

activationarr_movementmrr_snapshotproduct_usageconformed_dimensions

Design decisions

  • Accumulating snapshot for the signup → activation → paid funnel

    The PLG funnel has a small, well-defined set of milestones per signup (signup, first-value, paying conversion); an accumulating snapshot fact with three date role-plays lets a single row track elapsed time-to-activate, time-to-first-value, and time-to-paid for activation-rate and TTV reporting.

  • Event-grain ARR-movement fact for the ARR waterfall

    Modeling new / expansion / contraction / churn / reactivation as individual movement events with arr_amount_before/after and arr_delta makes the ARR waterfall a simple sum-by-movement-type and supports per-account churn-and-reactivation reconstruction.

  • Periodic monthly MRR snapshot for NRR / GRR cohort retention

    NRR and GRR are computed as ratios of cohort MRR across months; a month-end periodic snapshot at the account×month grain gives an additive base for cohort retention curves and trends without rebuilding from movement events.

  • Daily product-usage fact for adoption depth and health scoring

    Customer-health scoring blends frequency, depth, and feature breadth; a daily account×feature usage fact carries the additive session, event, and time-in-app measures that roll up to weekly / monthly adoption and feed the health-score model on the MRR fact.

  • SCD2 on account and user; previous-plan role-play on movement

    Segment, plan, CSM, and account status drift over time; SCD2 on dim_account and dim_user preserves as-was attributes for comparable cohort reporting, and a role-played previous_plan_key on fct_subscription_movement makes upgrade vs downgrade direction explicit without parsing surrogate history.

Tables in the SaaS Product-Led Growth & Retention Cohort Analytics model

Every table with its grain, columns, types and keys. PK marks a primary key, BK a business key and PII a column classified as personal data, which gets a masking strategy by default.

Fact tables (4)

fct_signup_activation

Grain: one row per signup — accumulating snapshot of activation journey

Accumulating snapshot — activation funnel from signup to paying conversion.

ColumnTypeKeys
signup_activation_keybigintPK
signup_date_keybigint
first_value_event_date_keybigint
paying_conversion_date_keybigint
user_keybigint
account_keybigint
plan_keybigint
acquisition_channel_keybigint
signup_idvarchar
time_to_activate_minutesinteger
time_to_first_value_minutesinteger
time_to_paid_daysinteger
sessions_in_first_weekinteger
currencyvarchar
activated_flagsmallint
converted_to_paid_flagsmallint
is_self_serve_signupboolean
signup_sourcevarchar

fct_subscription_movement

Grain: one row per ARR movement event (new / expansion / contraction / churn / reactivation)

Event-grain ARR movement fact — powers the ARR waterfall.

ColumnTypeKeys
subscription_movement_keybigintPK
event_date_keybigint
account_keybigint
plan_keybigint
previous_plan_keybigint
movement_type_keybigint
subscription_idvarchar
arr_amount_beforedecimal
arr_amount_afterdecimal
arr_deltadecimal
mrr_deltadecimal
seats_beforeinteger
seats_afterinteger
seats_deltainteger
currencyvarchar
movement_typevarchar
is_downgradeboolean

fct_monthly_recurring_revenue

Grain: one row per account per month — periodic snapshot of MRR / ARR composition

Periodic month-end snapshot — drives NRR / GRR cohort retention curves.

ColumnTypeKeys
monthly_recurring_revenue_keybigintPK
month_keybigint
account_keybigint
plan_keybigint
customer_segment_keybigint
mrr_amountdecimal
arr_amountdecimal
seats_countinteger
active_users_countinteger
monthly_active_usersinteger
expansion_arr_mtddecimal
contraction_arr_mtddecimal
churn_arr_mtddecimal
health_scoredecimal
currencyvarchar
is_payingboolean
is_at_riskboolean
is_expandingboolean

fct_product_usage_daily

Grain: one row per account × feature × day — periodic product-usage snapshot

Daily product-usage fact — feeds adoption, depth, and health scoring.

ColumnTypeKeys
product_usage_daily_keybigintPK
usage_date_keybigint
account_keybigint
feature_keybigint
unique_active_usersinteger
sessions_countinteger
events_countinteger
time_in_app_secondsinteger
features_adoptedinteger
depth_scoredecimal
adoption_pctdecimal

Dimension tables (9)

dim_date

Grain: one row per calendar day

ColumnTypeKeys
date_keybigintPK
full_datedateBK
day_of_monthsmallint
month_numbersmallint
quartersmallint
yearsmallint
week_of_yearsmallint
is_business_dayboolean

dim_month

Grain: one row per calendar month (cohort / MRR snapshot grain)

ColumnTypeKeys
month_keybigintPK
month_labelvarcharBK
yearsmallint
quartersmallint
fiscal_periodvarchar

dim_user

Grain: one row per product user per SCD2 version

SCD type 2

ColumnTypeKeys
user_keybigintPK
user_idvarcharBK
user_emailvarcharPII
user_rolevarchar
account_idvarchar
signup_datedate
first_login_datedate
last_login_datedate
is_activeboolean

dim_account

Grain: one row per customer account per SCD2 version

SCD type 2

ColumnTypeKeys
account_keybigintPK
account_idvarcharBK
account_namevarchar
industryvarchar
employee_size_bandvarchar
countryvarchar
signup_cohort_monthvarchar
customer_segmentvarchar
acquisition_channelvarchar
csm_idvarchar
account_statusvarchar

dim_plan

Grain: one row per subscription plan

ColumnTypeKeys
plan_keybigintPK
plan_idvarcharBK
plan_namevarchar
plan_tiervarchar
billing_frequencyvarchar
list_price_mrrdecimal
seat_basedboolean
is_activeboolean

dim_acquisition_channel

Grain: one row per acquisition channel

ColumnTypeKeys
acquisition_channel_keybigintPK
channel_idvarcharBK
channel_namevarchar
channel_categoryvarchar

dim_movement_type

Grain: one row per ARR movement type

ColumnTypeKeys
movement_type_keybigintPK
movement_typevarcharBK
descriptionvarchar
is_positive_arr_impactboolean

dim_customer_segment

Grain: one row per customer segment / health tier

ColumnTypeKeys
customer_segment_keybigintPK
segment_idvarcharBK
segment_namevarchar
ltv_bandvarchar
health_segmentvarchar

dim_feature

Grain: one row per product feature

ColumnTypeKeys
feature_keybigintPK
feature_idvarcharBK
feature_namevarchar
feature_categoryvarchar
is_premiumboolean
launched_datedate

Relationships

Each relationship is a foreign key on the first table referencing the second.

  • fct_signup_activation.signup_date_key → dim_date (many-to-one)
  • fct_signup_activation.first_value_event_date_key → dim_date (many-to-one)
  • fct_signup_activation.paying_conversion_date_key → dim_date (many-to-one)
  • fct_signup_activation.user_key → dim_user (many-to-one)
  • fct_signup_activation.account_key → dim_account (many-to-one)
  • fct_signup_activation.plan_key → dim_plan (many-to-one)
  • fct_signup_activation.acquisition_channel_key → dim_acquisition_channel (many-to-one)
  • fct_subscription_movement.event_date_key → dim_date (many-to-one)
  • fct_subscription_movement.account_key → dim_account (many-to-one)
  • fct_subscription_movement.plan_key → dim_plan (many-to-one)
  • fct_subscription_movement.previous_plan_key → dim_plan (many-to-one)
  • fct_subscription_movement.movement_type_key → dim_movement_type (many-to-one)
  • fct_monthly_recurring_revenue.month_key → dim_month (many-to-one)
  • fct_monthly_recurring_revenue.account_key → dim_account (many-to-one)
  • fct_monthly_recurring_revenue.plan_key → dim_plan (many-to-one)
  • fct_monthly_recurring_revenue.customer_segment_key → dim_customer_segment (many-to-one)
  • fct_product_usage_daily.usage_date_key → dim_date (many-to-one)
  • fct_product_usage_daily.account_key → dim_account (many-to-one)
  • fct_product_usage_daily.feature_key → dim_feature (many-to-one)

Related templates

All templates →
Start for $1

From requirements to AI-ready context, in one platform.

Describe your business in a conversation, start from a template or connect your own database. Your first model is ready in minutes.

Get startedBook a demo

Plans from $1/month · cancel any time