gumroad icon indicating copy to clipboard operation
gumroad copied to clipboard

Add churn chart to analytics

Open ershad opened this issue 8 months ago • 32 comments

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: Image

Mobile: Image

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 avatar Apr 03 '25 09:04 ershad

@ershad bunch of images across your issues are broken fyi

jordibruin avatar Apr 04 '25 12:04 jordibruin

@ershad @jordibruin hey maintainers can I took up on this issue . I will create a PR soon

Akshitzz avatar Apr 07 '25 15:04 Akshitzz

Images are broken!

fahreziadh avatar Apr 09 '25 10:04 fahreziadh

~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!

ershad avatar Apr 09 '25 13:04 ershad

@slavingia So you seriously are not going to add any churn reporting? This is a gaping hole in your subscription system.

jpcoder2 avatar Jun 11 '25 13:06 jpcoder2

Open to it but other higher priority things and I think api + MCP may be a better fit anyway.

slavingia avatar Jun 11 '25 13:06 slavingia

I didn't see churn listed in the issue above btw...

slavingia avatar Jun 11 '25 13:06 slavingia

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.

jpcoder2 avatar Jun 11 '25 13:06 jpcoder2

Makes sense! I'll have a designer just do that and we can add that.

slavingia avatar Jun 11 '25 13:06 slavingia

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!

jpcoder2 avatar Jun 11 '25 13:06 jpcoder2

@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: Image

Mobile: Image

Let me know what you think! Figma

laugardie avatar Jun 13 '25 10:06 laugardie

Looks great!

slavingia avatar Jun 13 '25 14:06 slavingia

Thanks, @laugardie. I'd be happy to take this on if that's okay with you, @slavingia

chinmoykalita avatar Jun 20 '25 07:06 chinmoykalita

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

chinmoykalita avatar Jun 23 '25 19:06 chinmoykalita

Option 1 sounds good!

slavingia avatar Jun 23 '25 19:06 slavingia

I think there's probably a better solution, happy to chat offline about what we can do. [email protected]

slavingia avatar Aug 28 '25 17:08 slavingia

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.

chinmoykalita avatar Sep 30 '25 20:09 chinmoykalita

@slavingia would love your quick take on this when you get a chance

chinmoykalita avatar Oct 06 '25 14:10 chinmoykalita

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.

slavingia avatar Oct 06 '25 14:10 slavingia

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

chinmoykalita avatar Oct 08 '25 20:10 chinmoykalita

Change our approach to match stripe’s. May want a designer to chime in if it requires product thinking but that seems easier.

slavingia avatar Oct 09 '25 16:10 slavingia

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?

slavingia avatar Oct 09 '25 16:10 slavingia

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?

chinmoykalita avatar Oct 10 '25 11:10 chinmoykalita

But you just said Stripe only supports 30 days above?

slavingia avatar Oct 10 '25 13:10 slavingia

Better to have someone else do this, as I don’t really think you understand the scope of the problem and the correct solution.

slavingia avatar Oct 10 '25 13:10 slavingia

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.

chinmoykalita avatar Oct 10 '25 14:10 chinmoykalita

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

EmCousin avatar Oct 21 '25 11:10 EmCousin

@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?

sm17p avatar Oct 21 '25 23:10 sm17p

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.

hchhabra avatar Oct 23 '25 11:10 hchhabra