Metric · Revenue

What is failed-payment rate, and how do you measure it in Metabase?

Failed-payment rate is the share of recurring charges that fail — expired cards, insufficient funds, declines. It's the leading cause of involuntary churn, and unlike voluntary cancellations it's often recoverable with better dunning. Measure it in Metabase from billing data synced into a database (Stripe, Chargebee, Paddle, or Recurly).

TL;DR — Failed-payment rate = failed charges ÷ attempted charges on renewals. Pair it with a recovery rate (how many failures are later paid via dunning) — the gap is involuntary churn.

How is failed-payment rate calculated?

Failed-payment rate = failed charges ÷ attempted charges, scoped to recurring renewals (not one-time or manual invoices). Then track two follow-on numbers:

  • Recovery rate — of the payments that failed, how many were eventually collected through retries and dunning.
  • Involuntary churn — failures that were never recovered and ended the subscription.

Dunning & recovery

Dunning is the retry-and-notify process after a payment fails: smart retries on optimal days, email/in-app prompts to update the card, and a grace period before cancellation. Most billing tools run this automatically — measuring recovery rate tells you whether it's working.

  • Watch the failure reason mix — expired cards recover far better than hard declines.
  • Report recovered revenue as an offset to gross involuntary churn.

What data does failed-payment rate need?

  • Invoice or charge records with a status (paid, failed, uncollectible).
  • A way to isolate recurring renewals from one-time charges.
  • Retry/attempt counts and failure reason codes for recovery analysis.

SQL patterns

Failed-payment rate by monthPostgreSQL

Failed renewal invoices as a share of attempted renewals.

SELECT
  date_trunc('month', created) AS month,
  COUNT(*)                                            AS attempted,
  COUNT(*) FILTER (WHERE status = 'failed')           AS failed,
  ROUND(100.0 * COUNT(*) FILTER (WHERE status = 'failed')
    / NULLIF(COUNT(*), 0), 2)                         AS failed_payment_pct
FROM invoices
WHERE billing_reason = 'subscription_cycle'
GROUP BY 1
ORDER BY 1;
Dunning recovery ratePostgreSQL

Of invoices that failed at least once, how many were ultimately paid.

-- Of invoices that failed first attempt, how many were later paid?
SELECT
  date_trunc('month', created) AS month,
  COUNT(*) FILTER (WHERE status = 'paid'
    AND had_failed_attempt)                           AS recovered,
  COUNT(*) FILTER (WHERE had_failed_attempt)          AS ever_failed,
  ROUND(100.0 * COUNT(*) FILTER (WHERE status = 'paid' AND had_failed_attempt)
    / NULLIF(COUNT(*) FILTER (WHERE had_failed_attempt), 0), 2) AS recovery_pct
FROM invoices
GROUP BY 1
ORDER BY 1;

Pitfalls

Including one-time charges.→ Scope to recurring renewals, or manual/one-time invoices distort the rate.
Ignoring recovery.→ A high failure rate with strong dunning recovery is very different from one without — always report both.
Counting retries as new failures.→ Decide whether the denominator is charge attempts or unique invoices, and stay consistent.
Treating it as voluntary churn.→ Failed payments are involuntary — the fix is dunning and card updates, not product or pricing.

Where this metric applies

Analytics

Metrics

FAQ

What causes involuntary churn?
Failed recurring payments that are never recovered — most often expired or replaced cards and insufficient funds. Dunning (retries plus card-update prompts) is how you claw much of it back.
What's a typical failed-payment rate?
It varies with card mix and geography; a meaningful share of renewals fail on first attempt. What matters more is your recovery rate — how much of that you win back through dunning.
Does my billing tool handle dunning automatically?
Stripe, Chargebee, Paddle, and Recurly all run automated retries and dunning emails. This metric tells you how effective that automation is for your customer base.