Add churn chart to analytics
What
Add a new “Churn” tab to the Analytics page, visible only to creators with subscription products. The chart is filterable by daily/monthly, product, and date range as in sales. Show Churn rate, Last period churn rate, Revenue lost, and Churned users in the highlights to give creators a quick snapshot of how their subscriptions are doing both in terms of retention and revenue.
Desktop:
Mobile:
Churn Calculation:
Churn rate for a period = (Number of cancelled subscriptions in the period / (Number of active subscriptions at the beginning of the period + Number of new subscriptions added in the period)) x 100
Where period can be a day or a month or a custom date range depending on the selected filters (please see designs above).
In highlights, "Churn rate" is current period's (day/month/custom date range) churn rate, "Last period churn rate" is last period's (day/month/custom date range) churn rate, "Revenue lost" is the sum of monthly recurring revenue for the subscriptions churned in the current period, and "Churned users" is the number of churned subscriptions in the current period.
Some reference docs on churn rate calculation are here, here, here, and here.
Why
To give creators better insight into where their revenue is coming from and how quickly it's shrinking/growing.
@ershad bunch of images across your issues are broken fyi
@ershad @jordibruin hey maintainers can I took up on this issue . I will create a PR soon
Images are broken!
~Could someone please share a screenshot? I can see the images in the description, even when I'm not logged in.~
Thanks to @laugardie, who has fixed the broken images. Please let us know if there are any issues with the images or links!
@slavingia So you seriously are not going to add any churn reporting? This is a gaping hole in your subscription system.
Open to it but other higher priority things and I think api + MCP may be a better fit anyway.
I didn't see churn listed in the issue above btw...
I didn't see churn listed in the issue above btw...
It's the last image. I requested churn reporting a good while back. I don't really care about any of the other charts in this issue, but churn would be very handy.
Makes sense! I'll have a designer just do that and we can add that.
Makes sense! I'll have a designer just do that and we can add that.
Sounds good. If you can add it to all UIs (I normally only use the desktop web interface) that would be great! Thanks!
@slavingia just reviewed this feature.
What do you think about adding a new “Churn” tab, visible only to creators with subscription products? I kept the chart style consistent with other Gumroad analytics views, but used blue instead of pink to signal that churn is more diagnostic, unlike growth-focused tabs like Sales or Following (which use pink).
The chart is filterable by daily/monthly, product, and date range as in sales.
I also added Churn rate, Last period churn rate, Revenue lost, and Churned users to the highlights to give creators a quick snapshot of how their subscriptions are doing both in terms of retention and revenue. Open to removing or simplifying if it feels like too much up front.
Desktop:
Mobile:
Let me know what you think! Figma
Looks great!
Thanks, @laugardie. I'd be happy to take this on if that's okay with you, @slavingia
Churn Analytics Implementation: Which Calculation Method to Use?
I'm implementing churn analytics and need recommendations on the calculation approach. Testing with demo data revealed that traditional churn formulas can produce impossible results (>100%) for long periods when businesses start from 0 subscribers. The Issue
Standard churn calculation: (Number of customers lost during period / number of customers at the start of period) × 100
For "all time" periods starting from 0 subscribers, this creates mathematical impossibilities. Example: 24 churned users with average base of 19 = 126% churn rate.
Solutions
Option 1: Average Churn Rate (ref) Calculate average of daily/monthly rates: "Average daily churn: 2.3%" or "Monthly average churn". It will be always mathematically valid, consistent across periods.
Option 2: Net Churn (ref)
churn rate = (start_subscribers - end_subscribers) / start_subscribers
Can show growth as negative churn
It can still be problematic for 0-start periods
Option 3: Since First Sale Adjust period start to first_sale_created_at_for_analytics like sales analytics
-
Which approach fits Gumroad's analytics philosophy best? I'm leaning toward Option 1 for mathematical soundness, but wanted to check preferences.
-
Also questioning whether 'Last period churn rate' metric makes sense for churn analytics, unlike sales where period-over-period comparisons are meaningful. @slavingia
Option 1 sounds good!
I think there's probably a better solution, happy to chat offline about what we can do. [email protected]
Before opening a new PR, I'd like to confirm the exact calculation approach to ensure alignment with product intent.
In my previous comment, I outlined three methodologies for handling churn calculation,
Option 1 sounds good!
@slavingia confirmed Option 1 (Average Churn Rate) as the preferred approach.
My last PR implemented a weighted average based on active subscriber counts, but @rmarescu raised an important point here to discuss which method aligns with business intent.
Simple vs Weighted Average
How it works:
- Month 1: 1000 subs, 5% churn (weight: 1000)
- Month 2: 1000 subs, 10% churn (weight: 1000)
- Month 3: 100 subs, 20% churn (weight: 100)
Weighted avg: (51000 + 101000 + 20*100) / 2100 = 8.09% Simple avg: (5 + 10 + 20) / 3 = 11.67%
Trade-offs
Weighted average:
- Reflects the reality that more subscribers were exposed to the 5-10% rates
- Answers: "Across all subscriber-months, what % churned?"
- Can understate issues when subscriber base is declining (biased toward earlier, larger periods)
Simple average (alternative):
- Treats each period equally
- Answers: "What was the typical churn rate per period?"
- May overstate if one small period had unusually high churn
From a seller's perspective, which insight is more actionable:
- "8.09% of my subscriber-months churned" (weighted), or
- "My typical monthly churn rate was 11.67%" (simple)?
Once decided, we can document this calculation in the help center analytics page and add a reference link in the churn analytics UI.
@slavingia would love your quick take on this when you get a chance
I would copy what Stripe does.
The churn rate is measured by the sum of churned subscribers in the past 30 days divided by the number of active subscribers as of 30 days ago, plus any new subscribers in those 30 days.
The formula you quoted ("churned in past 30 days / (active 30 days ago + new in past 30 days)") Stripe: Help & Support is specifically designed for 30-day rolling window calculations, not for arbitrary date ranges or daily aggregation.
Challenges with applying it to our dashboard:
- Custom date ranges: For a 90-day period (May-July) or 10-day period, Stripe doesn't define how to apply this formula
- Daily aggregation: Would require overlapping 30-day windows, making it difficult to understand day-to-day changes
- Monthly view confusion: "September churn" would include August data due to the 30-day lookback
Alternative Approach:
The standard period-based formula works consistently across all views and date ranges:
Churn Rate = (Customers lost during period / Customers at start of period) × 100
Then Weighted Average Churn Rate (%) = (Σ(Period Churn Rate × Period Active Subscribers)) / Σ(Period Active Subscribers)
This method is also documented by Stripe in their educational resources: Subscription Churn 101 and Average Churn Rate guide. Benefits:
- Works for any date range (daily, monthly, custom)
- Intuitive interpretation ("September churn" uses September data)
- Mathematically consistent across all views
- Allows weighted averaging for multi-period analysis
Alternative Option: If we want to strictly follow Stripe's dashboard approach, we could simplify the churn page to show only monthly churn for the past 30 days (and other past months) (no custom date range or daily/monthly toggle).
Would love your input on which direction aligns better with product goals. @slavingia @rmarescu
Change our approach to match stripe’s. May want a designer to chime in if it requires product thinking but that seems easier.
If we want to strictly follow Stripe's dashboard approach, we could simplify the churn page to show only monthly churn for the past 30 days (and other past months) (no custom date range or daily/monthly toggle).
Implying stripe doesn’t have a way of showing churn for any other ranges?
I believe Stripe's "30 days" in their formula isn't a fixed constraint, it’s just their default reporting period and can be replaced with any period length (e.g., 7 days, 90 days, a full month, a quarter).
Here’s how the generalized formula looks:
Churn Rate (for period) = Churned in period / (Active at period start + New in period) * 100
Examples:
30-day period (e.g., September 1-30):
Churn Rate = Churned Sept 1-30 / (Active on Sept 1 + New subscribers till 30th) * 100
Churn rate = 50 churned/(150 active + 50 new subscribers) * 100 = 25%
90-day period (e.g., May 1 - July 31):
Churn Rate = Churned May 1-July 31 / (Active on May 1 + New May 1-July 31) * 100
Custom 15-day period (e.g., Oct 1-15):
Churn Rate = Churned Oct 1-15 / (Active on Oct 1 + New Oct 1-15) * 100
How this applies to our already designed UI:
- Top summary cards: Calculate churn for the full selected period using the formula above (not averaged)
- Chart (Daily view): Each point shows start to EOD churn.
- Chart (Monthly view): Each month calculated using start to end date as a period as shown in the first example
- Default view: Last 30 days
- Flexibility: Users can select custom date ranges while maintaining the same calculation methodology
This approach gives us Stripe's accuracy with the flexibility sellers need for custom reporting periods. Shall I go ahead with this @slavingia?
But you just said Stripe only supports 30 days above?
Better to have someone else do this, as I don’t really think you understand the scope of the problem and the correct solution.
But you just said Stripe only supports 30 days above?
That was my initial understanding from Stripe’s line:
The churn rate is measured over the past 30 days…
After revisiting it as a formula, I realized the 30-day window is just their default example, the same logic can be applied to any period (7, 30, 90 days, etc.):
This keeps consistency with Stripe’s logic while allowing flexibility for custom date ranges.
This issue needs clarification about what's needed - re comment from @hchhabra
We need a consensus about:
- The churn calculation formula
- The time period(s) we want to enable
cc @slavingia
@slavingia Question over UX for loading data
Is the below UX desired for loading and switching data points?
Or should we keep it like how we do in sales?
This issue needs clarification about what's needed - re comment from @hchhabra We need a consensus about:
- The churn calculation formula
- The time period(s) we want to enable
Regarding ^ above comment, updated the issue description with design details from this comment by @laugardie . Also tried to add some details on churn calculation along with reference docs from Stripe. cc @ershad @slavingia @laugardie to review please.