Portfolio Project — SaaS Revenue Analysis

End-to-end revenue analysis across 10,000 customers and 36 months.

MRR modeling, cohort retention, and channel segmentation to surface what blended reporting misses.

Customers 10,000
Time range 36 months
Stack Python · SQLite · Plotly Dash
Schema Star · 4 tables

A SaaS business three years in, approaching a plateau.

Leadership needs a clearer view of 3 things:

Whether the revenue base healthy, which customer cohorts are retaining well, and whether the right customers are being acquired by channel.

Since top-level metrics don't answer these questions reliably, this analysis builds the segmented view that does.

10K
Synthetic customers across 6 acquisition channels
$623K
Peak MRR reached at month 24
35
Cohorts tracked across 36 months
4
Tables in the star schema

The dataset is synthetic but realistic: logistic growth curve peaking at month 11, plan migrations (Starter → Growth → Enterprise), failed payments, reactivations, and one deliberately seeded anomaly designed to be invisible at the top level.


Revenue grew fast, then hit a plateau.

Each month's MRR movement is classified into five buckets: New, Expansion, Contraction, Churn, or Reactivation. The waterfall helps to show the composition of growth, and not just the net number.

Monthly MRR movement Jan 2023 – Dec 2025. Positive bars: New + Expansion + Reactivation. Negative bars: Contraction + Churn. Line: cumulative ending MRR.

The S-curve is clearly shown from the rapid growth through Year 1, expansion MRR compounding in Year 2, then net new MRR compressing in Year 3 as churn scales with the base and acquisition slows. By late 2025, the business has shifted into retention.

Every percentage point of churn costs more in Year 3 than it did in Year 1. The math changes when the base is large.


Overview

Cohorts are defined by month of first subscription. For each cohort, we track what percentage of original MRR is still active at each subsequent month.

MRR retention heatmap. Each row = signup cohort. Each column = months since signup. Green = high retention, red = low.
101.5%
Avg retention at M1 — net expansion outpaces early churn
81.2%
Avg retention at M12
71.6%
Avg retention at M24

Month 1 retention averages 101.5% because expansion revenue from early upgrades outpaces logo churn. After that, the curve decays consistently with no cohort significantly outperforming the average. By M24, average retention sits at 71.6%. The narrow P25-P75 band means cohort behavior is predictable, which makes LTV modelable. It also means the average seems like a reasonable estimate for most segments.

Average MRR retention with P25–P75 band. Truncated at M25 (minimum 10 cohorts required).

Drilling down

Channel retention at M12 ranges from 66% to 74% across all 6 acquisition channels. partner_referral sits at 66.3%, which is within the normal range. Nothing stands out here.

Logo retention by channel, all plan tiers. partner_referral sits at 66.3% at M12 — within the normal range of 66–74%.

Now filtering to Enterprise only.

MRR retention by channel, Enterprise plan only. partner_referral at 58.6% vs 75–83% for every other channel at M12.

A 17–24 percentage point gap.

Why is it invisible at the top level? Enterprise is only 13% of signups, but it's 48% of MRR. The Starter and Growth tier customers from partner_referral churn at normal rates, and they outnumber Enterprise customers by volume. Therefore, the top-level view averages it away.

partner_referral Enterprise churn

5.4%
per month

all other channels Enterprise churn

1.87%
per month — 3× lower

partner_referral M12 retention

58.6%
Enterprise MRR retained

other channels M12 retention

75–83%
Enterprise MRR retained

The low CAC is hiding the problem, not solving it.

LTV is modeled as average initial MRR × (1 / monthly churn rate), segmented by channel and plan tier. CAC is assumed from industry-representative benchmarks by channel.

LTV grouped by acquisition channel and plan tier. Dashed line = average Enterprise LTV across non-partner_referral channels.
Metric partner_referral Enterprise Other channels Enterprise avg
Monthly churn 6.05% 1.87%
Avg customer lifetime 16.5 months 52.0 months
LTV $4,654 $14,567
CAC $95 $60–$340
LTV:CAC ratio 49x (looks healthy) varies

partner_referral has the lowest CAC at $95 and a blended LTV:CAC of 49x, which looks strong. At the Enterprise tier specifically, monthly churn of 6.05% compresses average customer lifetime to 16.5 months versus 52 months for other channels. LTV comes out to $4,654 compared to $14,567 for other Enterprise segments.

The ratio is misleading due to the low CAC.


3 things this analysis supports:

A note on methodology: this anomaly was seeded deliberately to demonstrate the analytical approach. The same methodology applied to real data would surface equivalent patterns that aggregated reporting typically misses.