
Feb 20, 2026·10 min read
Building a Custom Subscription Analytics and Cohort Reporting Tool for SaaS Teams
Summarize this article
Aggregate MRR tells you where you are. Cohort analysis tells you why. The difference between a SaaS company that understands its revenue dynamics and one that doesn't is usually visible in the quality of cohort data leadership can access — and how quickly they can get it without involving a data analyst or waiting a week for a custom query to be written.
Off-the-shelf tools like ChartMogul and Baremetrics offer cohort views, but they're constrained by what data Stripe exposes. A custom subscription analytics tool built on your full data model answers questions those tools can't: Are customers acquired through a specific channel retaining better than others? Do annual contract customers who go through onboarding with a CSM show different expansion patterns than those who self-onboard? Which plan tier has the worst net revenue retention, and is it getting better or worse over time? These questions drive strategic decisions, but they're only answerable if you have the data infrastructure and the reporting interface to support them.
What Cohort Analysis Reveals That Aggregate Metrics Hide
A cohort is a group of customers who share a common starting condition — most commonly their signup month, though cohorts can also be defined by acquisition channel, product tier, or onboarding path. By tracking each cohort's revenue over time, you see dynamics that aggregate metrics completely obscure.
Product improvement over time. If newer cohorts retain better than older ones at the same period in their lifecycle, your product is getting better — specifically, better at delivering value to new customers. If newer cohorts perform the same or worse, your growth is masking a retention problem. An aggregate churn rate of 3% looks the same in either scenario.
Acquisition quality differences. A cohort of customers acquired through a promotional campaign that offered a steep discount may churn at 4x the rate of organically acquired cohorts. This signal is invisible in aggregate churn data but immediately obvious when cohorts are segmented by acquisition source. The implication isn't necessarily to stop running promotions — it might be to design them differently, or to apply different onboarding resources to those customers.
Expansion timing and triggers. Cohort analysis shows not just whether customers expand, but when in their lifecycle expansion tends to happen. If most expansion revenue from a given cohort arrives in months 8–14, that's a signal for when to run expansion conversations and what the right trigger events are. If a specific cohort is still expanding in year three while other cohorts have plateaued, understanding what's different about that cohort has direct strategic value.
Product-market fit at segment level. The retention curve shape — how quickly it declines and where it stabilizes — tells you whether a product has found retention equilibrium with a customer segment. A curve that keeps declining past month 12 without flattening means the product hasn't found a use case that customers stick with. A curve that flattens above 80% after month 6 means a large proportion of customers have found ongoing value. Different plan tiers and customer segments can have dramatically different curve shapes — and knowing which segments have strong retention is the input to almost every expansion strategy.
The Subscription Events to Capture
The raw material for cohort analysis is a complete log of subscription state changes. Most of this data exists in Stripe or your billing system, but it needs to be structured and stored in your own database to make cohort queries practical at any meaningful scale.
The events that matter for a complete cohort analysis: activation (a new customer starts a paid plan), upgrade (increase in MRR from an existing customer), downgrade (decrease in MRR), churn (subscription cancelled), reactivation (returning after cancellation), payment failure with recovery status, and free-to-paid conversion (if your product has a free tier).
Each event needs at minimum: customer ID, event type, timestamp, plan before the event (if applicable), plan after, MRR delta, and the customer's cohort identifier — typically their signup month or their first paid conversion date. If you're building on Stripe, most of this data is available via webhook events. The events need to be stored in your own database to make retrospective cohort queries tractable — querying Stripe's API in real time for cohort analysis across 1,000+ customers is too slow to be interactive.
Data quality at this layer determines everything. A subscription event log that has missing events, duplicate events, or events with incorrect timestamps produces cohort metrics that look plausible but are wrong in ways that are hard to detect. The investment in a robust event collection pipeline — webhook handling that's idempotent, that stores raw events before processing them, and that has clear failure modes — pays off in cohort analysis quality.
Building the Cohort Analysis Engine
The cohort analysis engine sits between the raw subscription event log and the reporting interface. Its job is to transform an event log (which is append-only and granular) into cohort-period-level aggregates (which are what the reporting UI actually queries).
The schema for cohort aggregates looks like: cohort identifier (signup month), period (number of months since cohort start, from 0 to N), cohort size at period 0 (number of customers who activated), active customers at this period, retained MRR at this period, expansion MRR added during this period, and contraction MRR lost during this period. These aggregates are precomputed — typically by a nightly batch job — so that UI queries are fast regardless of how many underlying events exist.
The main engineering challenge in building this correctly is mid-period event attribution. An upgrade that happens on the 15th of a month should affect that month's MRR metrics, but the customer belongs to their original cohort and their progression to month 6 (for example) should be calculated correctly from their actual signup date, not from a monthly calendar boundary. Getting event attribution right — and handling edge cases like upgrades immediately followed by downgrades, or same-day churn and reactivation — is where most DIY cohort tools have subtle bugs that only become apparent when someone cross-checks the numbers.
A test suite that validates cohort calculation outputs against known scenarios (a customer who churns in month 3, reactivates in month 5, and upgrades in month 7 should appear in the cohort metrics exactly this way) is essential for maintaining confidence in the calculations as the engine evolves.
Visualizing Retention, Expansion, and LTV
The three visualizations that generate the most operational decisions from cohort data:
Retention curves as a cohort heatmap. Rows are cohort months, columns are periods since signup (month 0, month 1, month 2, and so on). Cell values show the percentage of the cohort's original MRR that's still active at each period. Color coding — darker green for higher retention, red for lower — makes patterns immediately visible without needing to read individual numbers. A healthy SaaS product with good product-market fit shows retention curves that flatten above 70–80% after 6 months and stay flat. A product with a problem shows curves that keep declining past month 12 without stabilizing.
Net revenue retention by plan tier. Which plan tier retains and expands best, expressed as a percentage of original MRR retained (including expansion) at months 6, 12, and 24? A company with a starter tier at 85% NRR, a growth tier at 105% NRR, and an enterprise tier at 130% NRR has a clear story about where to focus expansion efforts and where to invest in churn reduction. This analysis is only possible when plan tier is part of the cohort data model — which it won't be in off-the-shelf tools that only know what Stripe knows.
LTV by acquisition channel. Joining cohort retention data with acquisition channel data from the CRM or marketing attribution system reveals which channels produce the most valuable customers over time. This often differs substantially from which channels produce the most customers — a channel with slightly lower conversion but significantly better 12-month retention can produce 2x the lifetime value of a high-conversion channel with weak retention. This calculation requires joining billing data with CRM or attribution data, which is only possible in a custom system with access to both.
Sharing Reports Across Teams
An analytics tool that only data analysts can use is engineering infrastructure, not a business asset. A custom subscription analytics tool should include a sharing layer that gives each team the specific view of the data that's relevant to their decisions, without requiring them to build their own queries or wait for analyst time.
Finance wants MRR movement reports. New MRR, expansion MRR, contraction MRR, churned MRR, and net new MRR for each month — the standard SaaS revenue waterfall. This report should be available on a fixed cadence (monthly) without anyone needing to run it manually.
Product wants feature adoption cohorts. Customers who used feature X in their first 30 days versus those who didn't — do they retain differently at month 6? This requires joining usage data with cohort retention data, which is where a custom tool built on your full data model has a decisive advantage over Stripe-based analytics.
CS wants at-risk account identification. Accounts whose usage or engagement has declined significantly in the past 30 days, or whose plan tier relative to their usage puts them at churn risk based on cohort-level patterns. This view converts cohort analysis from historical insight to forward-looking action.
Building role-appropriate saved views into the tool — so teams get the slice of data that's relevant to their workflows without needing an analyst intermediary — is what converts a reporting tool from engineering infrastructure into something that actually drives decisions across the organization.
Summarize this article

