Quick answer
Involuntary churn is lost revenue from subscriptions that end because payment failed, not because the customer chose to cancel. The usual causes are expired or replaced cards, insufficient funds, bank declines and payments that need the customer to authenticate. You reduce it with automatic retries, card updates, clear failed-payment emails and an easy way for customers to update how they pay.
Voluntary vs involuntary churn
| Voluntary churn | Involuntary churn | |
|---|---|---|
| What happens | The customer cancels | A payment fails and isn’t recovered |
| The customer’s intent | They decided to leave | Often none. Many don’t know there’s a problem |
| Typical causes | Price, missing features, low usage, switching tools | Expired card, new card number, insufficient funds, bank decline, authentication needed |
| Main fixes | Product, onboarding, support, asking why they leave | Retries, card updates, payment emails, in-app prompts |
| Where to look | Cancellation reasons and product usage | Failed payments and past-due subscriptions |
The distinction matters because the fixes are completely different. A customer whose card expired may be using your product every day. Better onboarding won’t keep them, and a usage-based warning won’t flag them. A reminder to update their card might.
Failed payment, past due and churned are three different things
It’s easy to use these interchangeably. In Stripe Billing, they’re separate stages:
- A failed payment is an event. A renewal invoice couldn’t be charged, and Stripe sends an
invoice.payment_failedwebhook. - Past due is a state. The subscription moves to
past_due. The customer is still a customer, and Stripe may retry the payment. - Churn is the end. If the retries run out, the subscription moves to whatever your settings say:
canceled,unpaid, leftpast_due, orpausedif it’s eligible.
Stripe’s documentation also says to revoke access when a subscription becomes unpaid, because payment has already been attempted and retried. If your settings leave failed subscriptions past_due indefinitely, you may have customers who look active but haven’t paid in months.
Not every failure can be retried. When the bank returns a hard decline, such as lost_card, stolen_card or authentication_required, Stripe keeps the retry schedule but only charges once there’s a new payment method. Those customers need to hear from you.
How involuntary churn shows up in MRR
When a failed payment leaves MRR depends on your tool’s rules:
- Stripe Billing keeps
past_duesubscriptions in MRR and removes them when they becomeunpaidor canceled. - Baremetrics, by default, removes customers who’ve been unpaid for 30 days or more, with an option to extend that to 60.
- OneMRR keeps a past-due subscription in MRR until it’s canceled, then counts it as churn.
Example
A customer pays $49 a month. Their card expires and the November 3 renewal fails. Retries run for two weeks. Their bank keeps declining, so on November 17 the subscription is canceled under your settings.
From November 3 to 17, that $49 is MRR at risk. On November 17 it becomes churned MRR. If the customer had updated their card on November 10, nothing would have shown up as churn at all.
So past-due MRR is worth watching as its own number: it’s revenue you’re about to lose unless someone acts.
How to reduce involuntary churn
1. Turn on automatic retries
Many failures are temporary: a card at its limit, a bank’s fraud check, a brief outage. Stripe’s Smart Retries picks when to retry based on signals about the card and the payment. For new Stripe accounts it’s on by default, with up to 8 retries within 2 weeks. You can choose a longer window, up to two months, or set your own schedule of up to three retries.
Longer windows recover more payments but leave customers in limbo longer. Two to three weeks is a common middle ground for monthly plans.
2. Let card details update themselves
When a bank issues a new card number or expiry date, Stripe’s automatic card updates can refresh the saved card without the customer doing anything. Check that it’s available for your account and card types, because coverage depends on the card network and issuer.
3. Send failed-payment and expiring-card emails
Stripe can email customers when a payment fails, when a card is about to expire, and when a payment needs them to authenticate. Turn these on, then check the copy. A good failed-payment email:
- Says plainly what happened and that their account is still active, if it is.
- Has one button that goes straight to a page where they can update their card.
- Says what happens next and when, without threatening.
- Comes from an address someone reads, so replies reach you.
A sequence of two to four emails over the retry window is enough for most products. More than that starts to feel like harassment.
4. Tell customers inside your product
Email gets missed. If someone logs in while their subscription is past due, show a banner with a link to update their payment method. It’s the moment they’re most likely to fix it.
Decide how long a past-due account keeps access. A short grace period avoids locking out good customers over a bank hiccup. Restricting some features after that gives them a reason to act without losing their data.
5. Plan for annual renewals
An annual customer’s card has had a year to expire. Send a reminder before the renewal date, include the amount, and link to where they can update their card. A failed $1,200 renewal costs as much MRR as twelve failed monthly payments.
6. Make it easy to come back
If the subscription does end, a short note with a link to resubscribe and a reminder that their data is still there can win back customers who never meant to leave.
Handling it in your own code
If you manage access yourself, listen for Stripe’s webhooks rather than polling. A minimal handler in Node.js might look like this:
switch (event.type) {
case "invoice.payment_failed": {
const invoice = event.data.object;
// attempt_count is how many tries so far; next_payment_attempt is when Stripe tries again.
await markPastDue(invoice.customer, invoice.attempt_count, invoice.next_payment_attempt);
break;
}
case "customer.subscription.updated": {
const sub = event.data.object;
if (sub.status === "active") await clearPastDue(sub.customer);
if (sub.status === "unpaid") await restrictAccess(sub.customer);
break;
}
case "customer.subscription.deleted":
await endAccess(event.data.object.customer);
break;
}
Verify the webhook signature before handling anything. If you use Stripe’s billing automations, note that next_payment_attempt arrives on invoice.updated rather than invoice.payment_failed.
Metrics that show involuntary churn
- Failed payment rate: failed renewal charges ÷ renewal charges attempted, per month.
- Recovery rate: failed payments later paid ÷ failed payments.
- Past-due MRR: the MRR of subscriptions that are currently past due.
- Involuntary churned MRR: MRR lost from subscriptions that ended after a failed payment, as a share of all churned MRR.
- Time to recover: how many days a recovered payment took.
Stripe’s recovery analytics covers failure and recovery rates for Stripe payments. If churn is a big bar in your MRR bridge, splitting it into voluntary and involuntary tells you which problem to work on first.
Where involuntary churn fits in
Payment recovery is plumbing: set it up well once, check the numbers monthly, and adjust. It rarely needs ongoing creativity. Voluntary churn is the harder, more interesting problem, because it’s about whether customers are getting value. For that side, see how to reduce SaaS churn.