There is a particular kind of renewal meeting that every CS team recognizes: the one where the customer has already made up their mind, and you are the last to know. The conversation is polite, the language is reasonable, and the outcome is fixed. You walk out thinking about what you could have said differently. The answer, usually, is that the conversation was not the problem. The problem was six weeks earlier, in a support ticket nobody flagged.
This piece is about what those tickets look like, where they appear in the data, and why the standard tools for tracking customer health almost never surface them in time to act.
What a churn signal actually looks like in support data
Support tickets are not filed by people who are satisfied. That is obvious. But the distinction that matters for churn prediction is not between "filed a ticket" and "did not file a ticket." It is between different kinds of ticket language, and the progression from one kind to another over time.
A customer who is frustrated but still invested writes tickets that read like debugging conversations: specific error messages, workflow details, explicit questions about what they expected versus what happened. The subject line is something like "Error on bulk import step 3" and the body includes a screenshot attachment. That kind of ticket is work. It represents effort. Customers who put in that kind of effort still believe the product can solve their problem.
The ticket language shifts when that belief starts to erode. Subject lines get shorter. The body text stops including context the agent would need to reproduce the problem. Questions about expected behavior disappear. Instead, you get declarative statements: "This is not working." "Same issue again." "Still broken after last week's update." These are not debugging tickets. They are documentation tickets. The customer is creating a record, not asking for help.
The third phase, and the most dangerous one, is the absence of tickets entirely. A customer who was filing five tickets per month drops to zero. On most health dashboards, this looks like improvement. Ticket volume is down, so the account is presumably healthier. In reality, the customer has stopped reporting problems because they have stopped expecting solutions. The support queue went quiet because the customer made a decision.
Why this does not show up in standard health score models
Most health score implementations treat support volume as one signal among many: log in frequency, feature adoption, NPS response rate, and so on. Volume gets weighted, averaged with the other inputs, and produces a composite number. The problem is that this approach flattens the temporal pattern. It does not distinguish between a customer who had five tickets in January and five in February versus one who had five in January and zero in February. Both accounts show the same total ticket count for the period. They look identical in the aggregate.
The other issue is that product usage metrics, which dominate most health score formulas, measure a different thing than support sentiment. An account can have stable product usage right through the decision to churn. B2B customers do not stop using a product the moment they decide to leave. They keep using it until the contract expires, sometimes running it in parallel with the replacement they have already selected. Login frequency and feature engagement tell you what is happening right now. They do not tell you what the customer thinks about it.
We are not saying product usage data is worthless for health scoring. It is valuable for identifying adoption problems at the early stage of an account. But by the time a renewal is 60 to 90 days out, the decision is being made in conversations with budget holders, not in the product itself. The signal that reflects that decision is in communication data: support tickets, email threads, call notes.
The window where intervention is still possible
From the support ticket patterns we have observed in accounts that went through a renewal cycle, the language shift described above typically becomes visible four to seven weeks before a hard renewal conversation. That window is meaningful because it is long enough to do something with.
A CSM who gets a flag at the six-week mark has time to schedule an executive business review rather than a standard check-in. They have time to loop in someone from the product team for a direct conversation about a specific workflow problem. They have time to coordinate with the account executive so the renewal conversation does not come in cold. None of those interventions are possible if the first signal you see is the customer's lack of responsiveness to renewal emails at week minus two.
The window exists. The question is whether you have a mechanism to see it.
Reading ticket subjects versus ticket body text
Subject lines are not the whole story. In Zendesk and most other support tools, the subject field is the customer-written summary, which tends toward brevity even in engaged tickets. A more reliable signal lives in the body text of the thread, particularly the first message in each ticket. This is where customers describe what they expected to happen versus what did happen, and that framing tells you a lot about their state of mind.
The specific language patterns worth watching for in body text include conditional doubt ("I assume this is supposed to work differently"), attribution language ("this keeps happening even after we followed your documentation"), and what might be called scope expansion ("at this point we're questioning whether the integration will ever be reliable"). These constructions are different in kind from standard bug reports. They signal a customer who has been accumulating a mental model about product reliability, not just reporting individual incidents.
Across a long ticket thread, the progression from specific to general language is itself a signal. The first ticket about a given problem is usually specific. If the same problem resurfaces three weeks later and the ticket body is shorter and more general, that compression is worth flagging. The customer has decided the problem is a pattern, not an isolated incident, and is no longer investing in providing full context.
What to do with the signal once you have it
A churn risk flag is only useful if it lands on someone who can act on it and knows what to do. The failure mode here is the same one that kills NPS programs: the signal gets collected, it sits in a dashboard, and nobody is accountable for responding to it within a defined window.
The intervention design that tends to work is simple in structure but requires discipline to execute. When a flag surfaces, the CSM gets an alert that includes the specific tickets that triggered it: not just a health score number, but the actual language that changed. That context matters because it shapes the conversation. A CSM who knows the specific issue that drove the language shift can open a conversation about it directly, rather than running a generic check-in that the customer will interpret as box-checking.
The second part of the intervention is routing. Not every churn risk flag requires the same response. An account where the language shift is concentrated around a single integration problem needs a different action than one where the language has become generally dismissive across multiple ticket categories. The former is a product support problem. The latter is a relationship problem. Mixing up the response does more harm than good.
The signal is already there
The frustration that drives churn does not appear for the first time in the renewal conversation. It was written down, in your own support system, weeks before the meeting. Ticket subjects, body text progressions, thread length compression, and subject-to-silence transitions are all there in the data you already collect. What most teams lack is not the data. It is the mechanism to read it at the right frequency and surface it to the right person with enough context to act.
That is the specific problem Sturdy is built to solve. We read the ticket and email threads your accounts are already generating and flag the language patterns that precede hard renewal conversations. Not a health score. Not a composite number. The actual language, flagged at the point where intervention is still possible.