CHURN ANALYSIS

How to find what predicts churn with your own customer data

Which customer attributes and events to collect, how to run cohort and relative-risk analysis, and how to avoid false positives and AI-invented numbers.

Published 8 min read

Every subscription business has a theory about why customers leave. “Customers from paid ads churn more.” “Teams that don’t invite a second user never stick.” Some of these theories are right. Many are not, and the only way to tell is to check them against your own data.

This guide covers what to collect, how to compare groups with cohort and relative-risk analysis, how to avoid the statistical traps that make random noise look like insight, and how to use AI to explain the results without letting it make up numbers.

Step 1: decide what “churn” means

Before any analysis, write down a definition. For example:

  • Churned: subscription cancelled or ended unpaid, and not reactivated within 30 days.
  • Observation window: the customer’s first 90 days, or a calendar period.
  • Who counts: paying customers only, or trials too (analyze them separately; trial conversion is a different question).

Separate voluntary churn (the customer cancelled) from involuntary churn (a payment failed and was never recovered). They have different causes. A prepaid card and a disappointed user are not the same problem. Our article on involuntary churn covers the payment side.

Step 2: collect the right attributes and events

You want data that existed before the customer churned and that you could act on. A good starting set:

Field Type Example values Why it matters
signup_date Attribute 2026-06-12 Cohorts; seasonality
signup_source Attribute google_ads, facebook_ads, organic, referral Channel quality, not just volume
plan Attribute starter, team Fit between plan and need
seats Attribute 1, 5, 20 Single-seat accounts often behave differently
company_size / country / industry Attribute 11-50, DE, agency Segment fit
trial_length_days Attribute 7, 14 Whether longer trials help
coupon_at_signup Attribute LAUNCH50, none Discount-acquired customers
payment_method Attribute card_credit, card_prepaid, sepa, link Involuntary churn risk
activated_at Event / date 2026-06-14 Did they reach the first value moment?
last_active_at Attribute 2026-09-30 Recency of use
key_feature_used Event count reports_created: 4 Depth of use
support_tickets Count 0, 3 Friction
nps_score Attribute 0 to 10 Stated satisfaction

Some notes on getting this right:

  • Define activation concretely. “Created a first project and invited one teammate within 7 days” is measurable. “Got value” isn’t.
  • Record values as of a point in time. If you compare churned customers’ last_active_at to active customers’, the churned group will look inactive because they churned. That tells you nothing. Use a fixed point, such as activity in the first 14 days.
  • Keep categories coarse. Twenty signup sources with three customers each can’t be analyzed. Group them (paid search, paid social, organic, referral, other).
  • Payment method data from Stripe. Card objects in Stripe include a funding field (credit, debit, prepaid or unknown) (Stripe API reference), which you can use without handling card numbers.
  • Mind privacy. Collect what you need, document why, and follow your privacy policy and local law.

Step 3: build cohorts and compare churn rates

The simplest useful analysis compares churn rates between groups that differ in one attribute.

Take everyone who signed up in a period long enough for churn to show up (for example, signed up in Q1, observed for 90 days). For each value of an attribute, count customers and churned customers.

Illustrative example (not real data):

Signup source Customers Churned in 90 days Churn rate
Organic 400 60 15%
Paid social 200 50 25%
Referral 100 10 10%

Relative risk

Relative risk (RR) compares each group’s churn rate to a baseline. Using organic as the baseline:

  • Paid social: 25% / 15% = RR 1.67. Customers from paid social churned about 1.7 times as often.
  • Referral: 10% / 15% = RR 0.67. Referral customers churned about a third less.

Relative risk is easy to explain to anyone in the company, which is its main advantage over more complex models. See relative risk for the formal definition.

Step 4: check whether the difference is real

A difference in a table is not automatically a finding. With small groups, chance alone produces large differences.

Sample size

Look at the counts, not just the percentages. If paid social had 20 customers and 5 churned, its 25% rate could easily be 10% or 45% with another month of signups. A practical rule: be skeptical of any group with fewer than a few dozen customers or fewer than about ten churn events, and say so in the report.

Confidence intervals

Report a range, not just a number. A 95% confidence interval for a relative risk tells you the range of values consistent with your data. With the illustrative table above, the interval for paid social comes out at roughly 1.2 to 2.3, so the higher risk is fairly clear. If it’s 0.8 to 3.4, you don’t know whether paid social is worse at all. The standard method uses the log of the relative risk; most statistics libraries compute it for you.

A quick version in Python, for one comparison:

import math

def relative_risk(a_churn, a_total, b_churn, b_total, z=1.96):
    rr = (a_churn / a_total) / (b_churn / b_total)
    se = math.sqrt(1/a_churn - 1/a_total + 1/b_churn - 1/b_total)
    low = math.exp(math.log(rr) - z * se)
    high = math.exp(math.log(rr) + z * se)
    return rr, low, high

# Paid social vs organic, illustrative numbers from the table above
print(relative_risk(50, 200, 60, 400))  # about (1.67, 1.19, 2.33)

Multiple comparisons

This is the trap most dashboards fall into. If you test 40 attributes at a 5% significance level, you should expect about 2 of them to look “significant” by pure chance, even if none of them matter. The more you slice, the more false findings you get.

Ways to handle it:

  • Decide on a short list of hypotheses first, and treat everything else as exploration.
  • Adjust for the number of tests. The Bonferroni correction (divide your significance threshold by the number of tests) is simple and strict. The Benjamini-Hochberg procedure controls the false discovery rate and is less conservative.
  • Confirm on new data. Find a pattern in Q1 signups, then check whether it holds for Q2. A finding that replicates is worth acting on.

Step 5: correlation, not causation

Even a solid, replicated relative risk tells you that an attribute goes together with churn. It doesn’t tell you the attribute causes churn.

Common ways this goes wrong:

  • Confounding. Paid social customers might churn more because they’re mostly solo freelancers, and solo freelancers churn more regardless of channel. Check the relationship within segments (paid social vs organic, among single-seat accounts only).
  • Reverse causation. Customers who file many support tickets might churn more, or customers who are already failing to get value file more tickets.
  • Selection. Customers who chose the annual plan are already more committed. Annual billing may not cause retention; committed customers may choose annual billing.

The way to establish cause is an experiment: change one thing for a random group and compare. For example, if activation looks like it predicts retention, test an onboarding change that increases activation for a random half of new signups and see whether retention follows. Our guide to testing retention offers covers the same holdout logic for cancel flow offers.

Step 6: turn findings into actions

Finding (example) Possible action How to verify
Paid social signups churn more Change targeting or landing page; compare cohorts Next quarter’s paid social cohort
Single-seat accounts churn more Prompt inviting a teammate during onboarding A/B test the prompt
Not activated by day 7 churns more Day 3 and 5 nudges, setup help A/B test the nudges
Prepaid cards fail renewals more Ask for a backup payment method, earlier reminders Compare renewal failure rate
Low NPS precedes cancellation Follow up on low scores within a week Compare churn for followed-up vs not

Using AI to explain results, safely

Language models are good at turning a table of results into a clear summary and a list of ideas. They are bad at arithmetic and will produce plausible-looking numbers that are wrong. The safe split is:

  1. Compute every number in code. Churn rates, relative risks, intervals, sample sizes and adjusted p-values come from a deterministic script or SQL query.
  2. Give the model only the computed results, as structured data, and ask it to explain them.
  3. Forbid new numbers. Instruct the model to use only figures present in the input, and check the output: every number in the summary should match a number in the results.
  4. Require caveats. Ask it to flag small samples, wide intervals and that the findings are correlations.
  5. Keep a human in the loop for anything that changes pricing, targeting or product.

A short prompt structure that works:

You are given churn analysis results as JSON. Each row has an attribute,
a value, customers, churned, relative_risk, ci_low, ci_high and
adjusted_p. Explain the three strongest findings for a non-technical
founder. Use only numbers that appear in the JSON. Mention sample size
for each finding. Say these are correlations, not causes. Suggest one
experiment per finding.

Checklist

  • Churn defined in writing, voluntary and involuntary separated.
  • Attributes recorded as of a fixed point in time.
  • Categories grouped so each has enough customers.
  • Relative risk with confidence intervals for each comparison.
  • Sample sizes shown next to every result.
  • Correction for multiple comparisons, or results confirmed on new data.
  • Confounders checked within segments.
  • AI summaries use only computed numbers.
  • Top findings turned into experiments.

How NoChurn helps

With NoChurn’s custom data, you send any customer attribute or usage event through the API, in batches, by CSV or with the SDK. NoChurn computes the statistics in code (relative risk, sample size and confidence) to find which attributes go with churn, then uses AI to explain the results and suggest actions, labeled as correlation, not cause. The same data, along with payment method and signup source, feeds the churn score given to each customer at signup. See the API reference and pricing.

PROMPT

Read https://www.nochurn.sh/llms.txt,
then follow https://www.nochurn.sh/docs/quickstart/
to add NoChurn to this app. Use a test key
(nc_test_…) until I say we go live.

Stop leaking revenue.

  • Free until $300 MRR
  • No card needed
  • Live in 10 minutes
  • Never a cut of what we recover