Как посчитать involuntary churn в SQL
Содержание:
Зачем разделять
Voluntary churn = customer сам cancel, не оправдал ожиданий. Involuntary churn = система cancel из-за failed payment (expired card, insufficient funds). Лечится разными способами: voluntary — продукт, involuntary — dunning + payment infra. Без разделения непонятно, куда вкладываться.
Voluntary vs involuntary
В таблице subscriptions обычно есть cancellation_reason:
user_cancel— voluntarypayment_failed— involuntaryexpired_grace— involuntarychargeback— involuntary
Involuntary в SQL
SELECT
COUNT(*) FILTER (WHERE cancellation_reason IN ('payment_failed', 'expired_grace', 'chargeback')) AS involuntary,
COUNT(*) FILTER (WHERE cancellation_reason = 'user_cancel') AS voluntary,
COUNT(*) AS total_churn
FROM subscriptions
WHERE churned_at BETWEEN '2026-04-01' AND '2026-04-30';Доля от total churn
WITH stats AS (
SELECT
COUNT(*) FILTER (WHERE cancellation_reason IN ('payment_failed', 'expired_grace', 'chargeback')) AS involuntary,
COUNT(*) AS total
FROM subscriptions
WHERE churned_at >= CURRENT_DATE - INTERVAL '90 days'
)
SELECT
involuntary,
total,
involuntary::NUMERIC * 100 / NULLIF(total, 0) AS involuntary_pct
FROM stats;В индустрии involuntary обычно 20-40% от total churn. Меньше = хороший dunning.
По причине
SELECT
cancellation_reason,
COUNT(*) AS churns,
SUM(mrr) AS lost_mrr,
COUNT(*) * 100.0 / SUM(COUNT(*)) OVER () AS pct
FROM subscriptions
WHERE churned_at >= CURRENT_DATE - INTERVAL '90 days'
AND cancellation_reason IN ('payment_failed', 'expired_grace', 'chargeback', 'user_cancel')
GROUP BY cancellation_reason
ORDER BY churns DESC;Топ-причина involuntary часто — expired_grace. Решается через update-card flow и smart retries.
Частые ошибки
Ошибка 1. Все churn как один. Без сегментации не понять, что лечить. Voluntary — продукт. Involuntary — billing.
Ошибка 2. Считать involuntary как «потерянных». 30-60% involuntary можно вернуть через dunning. Не списывайте сразу.
Ошибка 3. Не учитывать chargeback fees. Каждый chargeback дополнительно стоит $15-25. Учитывайте в lost revenue.
Ошибка 4. Все expired_grace как involuntary. Иногда юзер не обновил карту намеренно — это voluntary с маской involuntary. Сложно отделить.
Ошибка 5. Один dunning policy для всех сегментов. Enterprise — phone call. SMB — email + retry. SMB-эффективные методы не работают для enterprise и наоборот.
Связанные темы
- Как посчитать churn в SQL
- Как посчитать MRR churn в SQL
- Как посчитать grace period recovery в SQL
- Как посчитать payment success rate в SQL
FAQ
Какой involuntary normal?
20-40% от total churn для B2C. 5-15% для B2B Enterprise (annual contracts).
Как уменьшить?
Smart dunning, card updater services (Stripe), pre-expiry email-cards.
Involuntary считается в churn rate?
Обычно да. Некоторые компании отдельно «net churn excluding involuntary».
Card updater стоит подключать?
Stripe Card Account Updater — $0.25/match. Окупается для customers с высоким LTV.
Как повысить recovery rate?
A/B test разных dunning sequences. Можно поднять recovery с 30% до 60%.