Every churn post-mortem I have sat in sounds the same. The renewal date passes, the account does not sign, and someone on the call says "honestly, we knew that one was at risk." And they did know. Somebody knew in March that the champion had left. Somebody else knew that seat usage had dropped by half in April. The support lead knew there were four tickets about the same broken export in May.
Nobody put those three facts in the same place until the deal was already gone.
That is the actual churn prediction problem at a 50-person B2B company. It is not that the signal is missing. It is that the signal is scattered across a CRM, a product database, a helpdesk, and one person's memory, and there is no system that assembles it into a single number that somebody has to look at on a Monday morning.
So most teams do the obvious thing. They go looking for a churn prediction model. They read about XGBoost. They price a customer success platform at 30k a year. And six months later they have a risk score nobody trusts and a CSM who overrides it every week.
Here is what I actually recommend instead, and the math for why.
The math that kills most churn models before they start
A machine learning churn model needs training data. Specifically it needs churn events, because that is the thing it is learning to recognise. The rough floor most practitioners quote is a few hundred historical churn cases before a gradient boosting model produces anything better than a coin flip on the accounts you care about.
Now run your own numbers.
Say you have 200 customers. Say your logo churn is 12% a year, which is roughly the median for private B2B SaaS. That is 24 churn events a year. To get to 300 events you need twelve and a half years of history, during which your product, pricing, and ICP will have changed three times over. The old data is not describing the same company.
There is a second problem underneath the first one. Churn is a rare event, so the classes are badly imbalanced. If 3% of your accounts churn in a quarter, a model that predicts "nobody churns" is 97% accurate and completely useless. This is a well documented trap in the churn modelling literature, and it is why accuracy is the wrong metric to ask a vendor about. Ask about recall on the churned class, or ask what percentage of last year's churn the model flagged more than 60 days out.
I am not anti-ML. I am saying that at Series A and B volumes, the model is not the constraint. The data plumbing is. And once you build the plumbing, you will find the rules-based version gets you most of the way there.
You do not have a modelling problem. You have a plumbing problem.
Every company I have audited already had the churn signals sitting in three or four systems. The work is joining them on the account record and making one number visible to the person who can act on it.
What churn prediction actually means at your size
Drop the word prediction for a second. What you want is a system that answers one question every week: which accounts have moved in the wrong direction since last week, and why.
That is a diff, not a forecast. And a diff is easy to build.
The difference matters because it changes what you optimise for. A forecast wants to be right. A weekly diff wants to be early and specific. If your CSM gets an alert that says "Account X: primary admin has not logged in for 31 days, renewal in 74 days," that is more useful than a score of 62 out of 100, even if the score is technically better calibrated.
Health scores fail for exactly this reason. One case study found a model flagging 15% of accounts as at risk when only 3% actually churned the following quarter, and the false positives wore down trust in the signal until people stopped reading the alerts. Alert fatigue kills more churn programs than bad math does. If you want the longer version of that argument, I wrote about why most customer health scores lie.
The five signals that actually predict B2B churn
I have built this scoring layer maybe a dozen times. The signals that keep earning their place are below. Notice that four of the five are relationship signals, not product usage signals. That is the part B2C-shaped churn advice gets wrong about B2B: your buyer and your user are usually different people, and the buyer is the one who cancels.
1. The champion left or changed roles
This is the single strongest predictor I have seen, and almost nobody automates it. When the person who signed the contract leaves the company or moves to a different function, the renewal loses its internal advocate and the replacement has no sunk cost in your product.
You can catch this without buying anything expensive. Run your CRM contacts against a job-change signal on a weekly cadence. Clay does this well through waterfall enrichment, and you can also read it off email bounce behaviour, which is free. A hard bounce on a contact marked as the economic buyer should generate a task the same day, not sit in a suppression list.
Weight this heavily. In my experience an account that loses its champion inside the renewal window is at roughly double the base churn risk, and the damage is largest when the champion leaves quietly and the CSM finds out from an out-of-office reply in month two.
2. Usage concentration, not usage volume
Total usage going down is a lagging signal. By the time aggregate logins drop, the decision has usually been made.
The earlier signal is concentration. Count distinct active users per account per week. An account with 40 seats where 34 people logged in last quarter is healthy. The same account where all activity now comes from three people is in trouble, even if total session count is flat, because the product has quietly become one team's tool instead of a company standard. When those three people leave or get reassigned, the renewal has no constituency.
Track two numbers: distinct weekly active users, and the percentage of total activity coming from your top three users. When that percentage crosses 70%, flag it.
3. Support patterns, not support volume
More tickets does not mean more risk. Engaged customers file tickets. Silent customers file nothing and then leave.
What predicts churn is the shape of the tickets. Repeat tickets on the same issue mean the customer has hit something you have not fixed, and each repeat is another meeting where somebody internally says "this thing does not work." Tickets that escalate to the account owner's manager mean it has become political. And a sharp drop to zero tickets from an account that used to file two a month usually means they have stopped trying.
Build three flags off your helpdesk: same-issue repeat within 30 days, escalation to a named executive, and ticket volume dropping to zero for 60 days after a period of activity.
4. Silence in the 90 days before renewal
The renewal conversation should not be the first conversation of the quarter. Pull last-meaningful-contact date and compare it to renewal date. Any account with a renewal inside 90 days and no logged two-way interaction in the last 45 is a red flag, full stop.
The reason this works is that it measures your own behaviour, not the customer's. It catches the accounts your team has quietly deprioritised, which are exactly the accounts that churn. Half the risk in most books is self-inflicted. I covered the operational fix for this in the renewal management playbook.
5. Billing friction
Payment delays, downgrade requests, seat reductions at renewal, and any request for a shorter contract term. These are the least ambiguous signals you have because somebody had to take a deliberate action to create them. A seat reduction from 40 to 25 is not a soft signal. It is a customer telling you what next year looks like.
The mistake teams make is that billing lives in Stripe or an ERP and never reaches the CRM. That is a two-hour integration and it is the highest return two hours in this whole build.
Scoring: keep it stupid on purpose
Here is a starting weight set I have used with a mid-market client running about 180 accounts. Adjust it after you calibrate, but start here rather than starting from a blank page.
| Signal | Points | Why this weight |
|---|---|---|
| Champion left or changed role | 30 | Strongest single predictor, hardest to recover from |
| Seat or spend reduction requested | 25 | Explicit customer action, near certain intent |
| Top 3 users are over 70% of activity | 15 | Product has narrowed to one team |
| No two-way contact in 45 days, renewal under 90 | 15 | Measures your own neglect |
| Repeat ticket on the same issue | 10 | Unresolved friction becoming political |
| Payment late more than 15 days | 5 | Weak on its own, meaningful stacked |
Anything over 40 goes to a named owner with a 7-day response requirement. Anything over 60 goes to the VP.
Two rules that matter more than the weights. First, always show the component signals next to the total. A score of 55 tells a CSM nothing. "55: champion left 12 days ago, renewal in 61 days" tells them what to do this afternoon. Second, let people override the score, but require a text reason and log it. Those override reasons become your calibration data, and after two quarters they will tell you which weights are wrong better than any model tuning would.
Where the score has to live
This is where these projects die. The score gets built, it renders on a dashboard, and the dashboard gets opened during QBR prep once a quarter.
A risk score that requires someone to go and look at it is not a churn program. It is a report.
The score has to arrive where work already happens. In practice that means three destinations: a Slack alert to the account owner the moment an account crosses a threshold, a task created on the CRM record with a due date, and a line item in the weekly pipeline or CS meeting agenda that gets read out loud. The third one sounds low-tech and it is the one that actually changes behaviour, because it creates a person who has to explain why nothing happened.
We build this layer with n8n running on the client's own infrastructure, which keeps customer data inside their environment and avoids per-task pricing. The workflow reads product usage from the warehouse or the app database, pulls contact and renewal fields from HubSpot, pulls tickets from the helpdesk, computes the score, writes it back to the account record, and posts the diff. It runs every Monday at 6am. Total build time on a clean stack is under two weeks. If your stack is not clean, fix the CRM data quality first, because a score computed on stale renewal dates is worse than no score.
How to tell whether it is working
Do not measure the score's accuracy. Measure two things.
Lead time. For every account that churned, how many days before the renewal date did the system first flag it? If the median is under 30 days you have built a late-warning system, not an early one, and you need earlier signals. Aim for 90.
Save rate on flagged accounts. Of the accounts that crossed the threshold and got an intervention, what percentage renewed? Compare that against your base renewal rate. If flagged accounts renew at the same rate as everything else, either your signals are noise or your intervention playbook does nothing. Both are worth knowing.
Run this review once a quarter with the override log open. You will usually find one weight is badly wrong and one signal you thought mattered does not. Cut it. A five-signal score that people trust beats a fifteen-signal score they ignore.
When you should actually build the ML model
There is a real threshold. Once you are past roughly 1,000 customers, or you have three or more years of clean history with a few hundred churn events, gradient boosting starts to earn its keep. Reported AUC for well-trained models on B2B SaaS data lands in the 0.82 to 0.91 range, which is genuinely better than rules.
But notice what has to be true first: clean history, joined data, labelled churn reasons. Every one of those is a byproduct of building the rules-based system. You do not skip a step by buying a model. You just pay someone else to discover that your data is not ready.
The other honest reason to wait: a rules-based score is explainable. When a CSM asks why an account is red, you can answer in one sentence. When a model flags an account, you are into feature importance charts, and I have watched that conversation lose a room more than once.
Not sure which signals your data can actually support?
Book a free 30-minute audit. We will look at your CRM, product data, and last four quarters of churn, and tell you which three signals are buildable in a month.
Book an audit →FAQ
What is a churn prediction model?
It is any system that assigns a risk level to a customer account based on historical patterns in behaviour, engagement, and billing. In practice there are two versions. A rules-based score applies weights you defined to signals you chose. A machine learning model infers the weights from past churn events. For most B2B companies under 1,000 customers, the rules-based version performs comparably and is far easier to trust and maintain.
How much data do I need to train a churn model?
Practitioners generally want several hundred historical churn events before a machine learning model produces reliable output. At 200 customers and 12% annual logo churn you generate about 24 a year, which is not enough. The class imbalance makes it worse, since a model can score 97% accuracy by predicting nobody ever churns. Check recall on the churned class instead.
Which signals predict B2B SaaS churn best?
In my experience the strongest is a champion leaving or changing roles, followed by explicit billing actions like seat reductions or downgrade requests. Usage concentration, where all activity narrows to two or three people, is a better early signal than total usage decline. Support ticket shape matters more than volume, and silence before a renewal is often self-inflicted risk worth tracking.
Do I need a customer success platform to do this?
No. You need your product usage data, your helpdesk data, and your billing data joined onto the account record in your CRM, plus something to compute the score on a schedule. HubSpot custom properties plus n8n covers it at a fraction of the cost. Buy a platform when you have enough CSMs that workflow management itself is the bottleneck, not before.
How far in advance can churn be predicted?
Realistically 60 to 120 days for annual contracts, if your signals include relationship and billing data rather than usage alone. Usage decline tends to appear 30 to 45 days out, which is usually too late to change the outcome. Measure your own lead time by checking, for each churned account, how many days before renewal the system first flagged it.
Where to start
Do not start with tools. Start with the autopsy. Pull your last 20 churned accounts, and for each one write down what was knowable 90 days before the renewal date. It takes an afternoon, it is uncomfortable, and it will produce a better signal list than any vendor demo.
Then build the smallest version that fires an alert at a real person. Five signals, one weekly job, one Slack channel. You can always add the model later, and by then you will have the data to train it on.
If you want help building the data layer underneath it, that is most of what we do at Ziel Lab. We also handle the automation layer that keeps the score fresh without anyone maintaining a spreadsheet. Get in touch and we will tell you honestly whether this is a two-week build or a two-month one for your stack.