Skip to content

SaaS Metrics

Cohort Retention Curves — The Chart That Tells You If Your SaaS Is Real

All articles
📈 ⏱️

The Plateau Is What Matters. Everything Else Is Noise.

Churn rate lies. Overall retention lies. They're single numbers that hide the mess inside your product. A 70% annual retention rate sounds alive but it could mean "50 customers left, 100 stayed" or "5,000 left, 17,000 stayed" — two completely different failure modes. You're watching an average and calling it a signal.

Cohort retention curves cut through the noise. Instead of one number, you get a table: signup month × month-since-signup. Row = cohort (all customers who signed up in June). Columns = M0, M1, M2, M3, M6, M12 retention. The curve tells you what actually happens to a customer after they sign up. Do they stick? When do they leave? Is there a bottom?

Why Cohort Curves Beat Overall Retention

Retention curves answer the question overall metrics hide: *Are we building a product people stay with, or just acquiring customers faster than they leave?* A SaaS with 85% overall retention might have 20% churn in month 1 (bad onboarding), climb back to 95% retention by month 6 (product works), then plateau flat at month 9+ (product-market fit). The curve shows all three. The "85%" number shows none of it.

Velocity X renders cohorts as a heatmap: rows = signup cohorts (Jan 2025, Feb 2025, etc), columns = months-since-signup. Each cell = retention % for that cohort at that timepoint. Colors run green (90%+) → yellow (70–89%) → red (< 50%). The pattern you're hunting: a plateau. M6 = 65%, M7 = 64%, M8 = 63%, M9 = 63%, M10 = 63%. Flat = healthy. Falling = leaky bucket. Rising = impossible but great if it happens.

The Heatmap Anatomy

The First Drop (M0 → M1): 70–90% is normal. If you're at 95%+ month 1, either your onboarding is flawless or you're too young to have real churn. If you're at 50%, your product is broken or your PMF is imaginary. The delta between signup and month 1 is pure onboarding health. Compare your M1 across three cohorts. If each cohort loses 10% in month 1, that's consistent (and fixable). If one cohort loses 30%, something changed — pricing, onboarding, product quality, CAC quality. Investigate.

The Middle Cliff (M2 → M4): Customers who aren't sticky by month 2 usually leave by month 4. You see a sharp drop here if the product doesn't deliver on the promise. If your curve is flat M1–M6, you nailed the core value prop. If there's a visible cliff at month 3, the product works initially but fails to engage deeply. Fix feature depth. Add automation. Reduce friction on the next "aha" moment.

The Plateau (M6+): This is the money column. If your retention stays flat from month 6 onward (±2%), you have product-market fit. Customers who make it to six months are staying. The absolute percentage matters less than the flatness. 55% flat = healthier than 70% falling. A falling curve at month 8+ means something broke — payment friction, a bad update, competitor moved in, support response time dropped. A flat curve means your core customers are anchored.

The SQL: Real Data From Supabase

Velocity queries two CTEs: signups (who joined when) and activity (who stayed). The pattern:

WITH signups AS ( SELECT DATE_TRUNC('month', created_at) as signup_month, id as customer_id, created_at FROM customers ), activity_by_month AS ( SELECT s.signup_month, s.customer_id, DATE_TRUNC('month', a.activity_date) as activity_month, EXTRACT(MONTH FROM DATE_TRUNC('month', a.activity_date) - DATE_TRUNC('month', s.created_at)) as months_since_signup FROM signups s LEFT JOIN ( SELECT DISTINCT customer_id, DATE(created_at) as activity_date FROM events WHERE event_type IN ('login', 'action', 'export', 'invite') ) a ON s.customer_id = a.customer_id AND DATE_TRUNC('month', a.activity_date) >= DATE_TRUNC('month', s.created_at) ), cohort_retention AS ( SELECT signup_month, months_since_signup, COUNT(DISTINCT customer_id) as cohort_size, COUNT(DISTINCT CASE WHEN activity_month IS NOT NULL THEN customer_id END) as active_count FROM activity_by_month WHERE months_since_signup >= 0 AND months_since_signup <= 12 GROUP BY signup_month, months_since_signup ) SELECT signup_month, cohort_size, ROUND(100.0 * MAX(CASE WHEN months_since_signup = 0 THEN active_count ELSE 0 END) / cohort_size, 1) as m0, ROUND(100.0 * MAX(CASE WHEN months_since_signup = 1 THEN active_count ELSE 0 END) / cohort_size, 1) as m1, ROUND(100.0 * MAX(CASE WHEN months_since_signup = 3 THEN active_count ELSE 0 END) / cohort_size, 1) as m3, ROUND(100.0 * MAX(CASE WHEN months_since_signup = 6 THEN active_count ELSE 0 END) / cohort_size, 1) as m6, ROUND(100.0 * MAX(CASE WHEN months_since_signup = 12 THEN active_count ELSE 0 END) / cohort_size, 1) as m12 FROM cohort_retention GROUP BY signup_month, cohort_size ORDER BY signup_month DESC;

The query groups customers by signup month, tracks activity across calendar months, then computes retention % at 0, 1, 3, 6, 12 months. Query time: sub-second. Refresh daily. This is the query that powers Velocity's cohort heatmap.

Reading the Plateau

Healthy plateau: M6 ≥ 65%, M6–M12 ±3 percentage points, curve is visibly flat. This customer is yours for the long game. Weak plateau: M6 = 50%, M12 = 45%. The curve falls gradually. You're slowly bleeding customers even after six months. Investigate: Is the competitor cheaper? Is your support team slow? Did you deprecate a beloved feature? Absent plateau: Curve keeps falling M1–M12. Every month loses 5%+ more customers. Your product doesn't create ongoing value. You're selling one-time utility, not a habit.

Red Flags (And How to Fix Them)

No Flat Section = no sticky core. Fix the product. Reduce sign-up friction (are you qualifying leads properly or onboarding trash?). Add weekly activation moments (emails, in-app nudges). Deepen integration — embed the product into the customer's workflow so leaving is costly. M1 drop below 60% = broken onboarding. Video? Walkthrough? Demo call? One of them isn't working. M3–M4 cliff = shallow feature set or bad education. Customers get value for 2 months, then hit a ceiling. Expand the product roadmap or teach them to go deeper with the existing features. Plateau falling at M8+ = churn event. Something changed. Email receipts? Payment friction? New competitor? Interview your churned customers from months 8–10.

Six FAQs

What counts as "activity"?

Login is the safest. Any action (create, edit, share, export) counts. Avoid counting emails opened or notifications sent — those are marketing metrics, not product usage. If a customer hasn't logged in in 60 days, they're gone, even if they read your newsletter. The SQL above uses logins + actions. Adjust event_type list to your product.

Should I include free-trial users in cohorts?

Yes, but separate them. Create two heatmaps: one for trial → paid (the real metric) and one for all signups (includes churned trials). The trial cohort will have a cliff at the conversion point — that's expected. Paid cohorts show true product stickiness. If your free trial has 40% → paid conversion but 80% → month 1 retention (paid), your onboarding works and pricing is the bottleneck.

What if months are too granular?

Use weeks or days. Adjust DATE_TRUNC to 'week' or just date. Weekly cohorts are noisier but fresher — you see retention patterns in 4 weeks instead of waiting 8 months. Monthly cohorts are smoother, better for annual contracts. Pick whatever matches your sales cycle.

How many cohorts do I need before the curve matters?

Ten, minimum. Five is better. With three cohorts, one bad month skews the average. With ten cohorts, outliers smooth out. At 20+ cohorts, the heatmap starts showing true patterns. If you're pre-product market fit (under 6 months of data), watch weekly cohorts and don't panic over noise.

Can I adjust for seasonality?

Yes. If you're B2B SaaS, summer churn might spike due to holidays. Create a "adjusted retention" column that factors in monthly churn rates: if July always loses 5% extra, flag it in your analysis. For consumer SaaS, look for seasonal patterns in cohort data. If Jan cohorts always plateau at 45% and July cohorts at 60%, that's meaningful signal about your audience or product fit.

What's a good plateau number?

Depends on your model. Horizontal SaaS (tools used by many industries): 50%+ is healthy. Vertical SaaS (industry-specific): 60%+. Enterprise SaaS: 70%+. Consumption-based (pay-per-use): 30%+ is normal due to volatility. The shape matters more than the number. A 40% flat curve is healthier than a 70% falling curve.

The Bottom Line

One retention number is a trap. A cohort heatmap is a mirror. It shows you what customers *actually do* after they sign up, not an average across three cohorts and 18 months of noise. Build the table. Set it to refresh nightly. Look at month 6: is it flat? Yes = ship faster, expand features, hunt for expansion revenue. No = something in the product doesn't stick. Fix it before burning more on CAC. The plateau is the truth. Everything else is marketing.

Ready to see your cohort curves? Check Velocity pricing for the full SaaS metrics suite, or explore customer health scoring to turn retention data into action.

Let us make some quick suggestions?
Please provide your full name.
Please provide your phone number.
Please provide a valid phone number.
Please provide your email address.
Please provide a valid email address.
Please provide your brand name or website.
Please provide your brand name or website.