Most SaaS teams know which customers “feel healthy,” but turning that intuition into a system you can trust is harder than it sounds. If your account managers track risk in spreadsheets and ad-hoc notes, you’re flying blind. A good customer health score replaces guesswork with repeatable signals, calibrated thresholds, and playbooks that trigger the right action at the right time.
This guide walks you through designing a health score that your customer success (CS), product, and revenue teams will actually use. We’ll cover the data model, normalization, recency decay, weights and bands, dashboards, alerts, and the operational playbooks that close the loop. You’ll also see concrete examples and prompts you can use to build these components with YeshBe, an AI-powered Vibe Coding platform for building real software by describing what you want. YeshBe doesn’t hand you a prefab CS system; instead, you’ll build a custom health-scoring tool that fits your product and workflow.
Define success before you pick signals
A health score should predict outcomes you care about in the next 30–90 days. Pick one or two primary outcomes so you can test whether the score correlates with reality:
- Renewal likelihood (churn vs. renew)
- Expansion potential (upsells within a timeframe)
- Product risk (escalations, SLA breaches)
Write down a short problem statement:
“Within 60 days, can we predict which customers will churn or expand, and trigger human or automated interventions early enough to change the outcome?”
Choose inputs that reflect behavior, outcomes, and friction
Great scores combine usage, sentiment, value delivery, and friction. Start with a few high-signal inputs. You can add more later, but simplicity helps you ship and iterate.
Common inputs
- Product engagement: weekly active users, feature adoption, task completions, sessions per seat.
- Value events: documents processed, workflows completed, projects shipped—domain-specific “moments of value.”
- Onboarding progress: time-to-first-value, key setup steps completed, time since last milestone.
- Support friction: ticket volume per user, backlog age, SLA breaches, bug count affecting the account.
- Sentiment: NPS/CSAT trends, verbatim feedback polarity (with care), stakeholder survey responses.
- Commercial signals: invoice status, payment failures, approaching contract end, seat utilization vs. purchased.
- Delivery and reliability: uptime incidents that impacted this tenant, performance regressions.
Each input should be measurable, explainable, and available at least daily. Avoid vanity metrics or signals you can’t refresh reliably.
Normalize inputs so they’re comparable
Inputs have different scales and distributions. Normalize them to a common 0–100 range before weighting:
- Min–max scaling within relevant cohorts (e.g., plan tier, region) to avoid penalizing small accounts.
- Log transforms for heavy-tailed counts (tickets, events) so outliers don’t dominate.
- Winsorization (cap extremes) to reduce noise from rare spikes.
Example normalization logic:
-- Example: normalize weekly active users per seat by plan WITH stats AS ( SELECT plan, PERCENTILE_CONT(0.05) WITHIN GROUP (ORDER BY wau_per_seat) AS p05, PERCENTILE_CONT(0.95) WITHIN GROUP (ORDER BY wau_per_seat) AS p95 FROM account_usage GROUP BY plan ) SELECT a.account_id, GREATEST(0, LEAST(100, 100.0 * (LOG(1 + a.wau_per_seat) - LOG(1 + s.p05)) / NULLIF(LOG(1 + s.p95) - LOG(1 + s.p05), 0) )) AS wau_score FROM account_usage a JOIN stats s ON s.plan = a.plan;
Apply recency decay
Recent behavior should count more than older events. Apply exponential decay to inputs measured over time:
-- Recency-weighted value events over 90 days SELECT account_id, SUM(event_value * EXP(-0.05 * days_ago)) AS value_signal FROM ( SELECT account_id, event_value, DATE_PART('day', NOW() - event_at) AS days_ago FROM account_value_events ) e GROUP BY account_id; Weight inputs to reflect your product’s model
Not all signals are equal. Start with a simple weighted average, document your rationale, and prepare to recalibrate.
- Usage and value events: 40–60% combined.
- Onboarding progress (for new logos): 10–20% for first 60–90 days.
- Support friction: 10–20% (negative weight).
- Sentiment (NPS/CSAT trend): 10–20%.
- Commercial risk (invoices, term): 10–20% (negative weight).
Example weighted score:
SELECT account_id, ROUND( 0.35 * usage_score + 0.25 * value_score + 0.15 * onboarding_score + -0.15 * support_friction_score + 0.10 * sentiment_score, 2 ) AS health_raw FROM normalized_inputs;
Use negative overrides for must-fix conditions
Some conditions drop the score regardless of other inputs:
- Invoice 30+ days overdue
- Open P1 incident affecting the account
- Security blocker during onboarding
CASE WHEN invoice_overdue_days >= 30 THEN LEAST(health_raw, 20) WHEN open_p1_incidents > 0 THEN LEAST(health_raw, 30) ELSE health_raw END AS health_capped
Create score bands with clear operational meaning
Continuous numbers are hard to act on. Convert to bands with playbooks:
- Red (0–39): At risk. Trigger immediate outreach and an executive check-in for strategic accounts.
- Yellow (40–69): Watchlist. Assign tasks for adoption nudges and confirm stakeholder alignment.
- Green (70–100): Healthy. Look for expansion signals and reference requests.
Make bands cohort-aware. A 45 in the first 14 days of onboarding might be green for a complex enterprise setup, but yellow for self-serve SMB.
Design a transparent dashboard CS will trust
Trust comes from explainability. Your dashboard should show:
- Overall score and band, with sparkline trend
- Top positive/negative contributors this week (e.g., “Usage up +8, SLA breaches -12”)
- Recent key events and milestones
- Alerts triggered and playbooks in progress
- Seat utilization, contract timeline, stakeholder map
Keep the visual language consistent: green for improvements, red for regressions, neutral gray for stable signals. Add tooltips describing how each signal is calculated.
Operationalize with alerts and playbooks
The score is useful only if it triggers action. Start with a small set of well-defined playbooks:
- Red band for two consecutive weeks: schedule a 30-minute health review, share a plan, and confirm ownership.
- Yellow band with low feature adoption: assign a success plan template with two targeted enablement modules.
- Green band with high utilization: send expansion discovery checklist and schedule QBR prep.
Alerts should be rate-limited (e.g., at most one per condition per week) and routed to the right channel (CS Slack, email, task system). Include a deep link back to the account’s dashboard.
Model multi-entity accounts and personas
Health often varies across teams and personas. Consider:
- Sub-account or workspace scores, rolled up to an org-level score with weights proportional to revenue or seat count.
- Stakeholder-level sentiment (economic buyer, champion, admin).
- Use-case-specific adoption bundles (e.g., “analytics module” vs. “automation module”).
Expose both the rollup and the components so CSMs know where to focus.
Cohorts, baselines, and fairness
Compare like with like. Separate baselines for different tiers, regions, or verticals reduce bias. For example, enterprise customers might have lower early usage but higher long-term value. Use cohort-specific normalization and thresholds, and display cohort context in the UI.
Calibrate with real outcomes
After 60–90 days, compare your score to outcomes. Look for:
- Score distribution across churned vs. renewed accounts
- Lead time: how many days before churn did the score turn red?
- False positives/negatives: red accounts that renewed and green accounts that churned
Tune weights and thresholds based on evidence. If available, try simple logistic regression with your normalized inputs to estimate coefficients, but keep explainability high for CS users.
Data model and ETL you can maintain
Plan a durable schema. You’ll need:
- accounts (id, name, plan, MRR, region, owner_id, contract_end_at)
- account_daily_signals (account_id, date, usage_score, value_score, onboarding_score, support_friction_score, sentiment_score, commercial_risk_score)
- account_daily_health (account_id, date, health_raw, health_capped, band)
- account_events (account_id, event_at, event_type, metadata)
- alerts (id, account_id, type, created_at, status, acknowledged_by)
- playbooks (id, account_id, playbook_type, started_at, status, owner_id)
Schedule daily recompute (or hourly for high-volume products). Keep the pipeline idempotent and traceable. Store the inputs and the final score so you can debug changes over time.
Security and privacy considerations
- Minimize PII in signals; use account and seat IDs rather than names when possible.
- Enforce least privilege: CS can see account-level metrics; engineers can see system metrics but not necessarily commercial data.
- Audit who changes weights, thresholds, and playbooks. Keep version history.
- Be careful with sentiment analysis of verbatim feedback; avoid sending sensitive text to external services without approval.
Build it with Vibe Coding in YeshBe
YeshBe lets you describe the data model, pipelines, UI, and workflows in natural language and refine them through conversation. You’re building a custom tool—not deploying a canned CS product—so you keep control over signals, transparency, and governance.
Prompts to jumpstart your build
Create a customer health scoring tool with these parts: 1) a daily ETL that ingests account usage, support tickets, NPS, and invoices; 2) normalization and recency decay; 3) weighted health score with negative overrides; 4) a dashboard with score, trend, top contributors, and recent events; 5) alerts to Slack when a score moves bands; 6) playbooks with tasks and due dates. Use the schema I describe next.
Schema: - accounts(id, name, plan, mrr, region, owner_id, contract_end_at) - account_daily_signals(account_id, date, usage_score, value_score, onboarding_score, support_friction_score, sentiment_score, commercial_risk_score) - account_daily_health(account_id, date, health_raw, health_capped, band) - account_events(account_id, event_at, event_type, metadata) - alerts(id, account_id, type, created_at, status, acknowledged_by) - playbooks(id, account_id, playbook_type, started_at, status, owner_id)
Build an admin settings page where authorized users can adjust input weights, recency decay factors, and band thresholds. Persist changes with versioning and show a changelog of configuration edits with who/when.
Add a "Top Contributors" widget that explains the weekly delta in the health score by listing the three largest positive and negative input changes with colored badges.
Create an alerting workflow: when an account moves from green to yellow or red, create an alert record, post to Slack channel #cs-alerts with a deep link to the account dashboard, and start a default playbook for the new band.
Testing and rollout
Before you roll out to the whole CS team:
- Backfill 90 days of data and compute historical scores.
- Run a shadow period where CSMs see the score but don’t act on it; collect feedback.
- Validate that alerts are actionable, not noisy. Tune rate limits and thresholds.
- Instrument the dashboard for usage: which widgets matter? What do CSMs click?
After go-live, hold weekly calibration sessions. Review 5–10 accounts across bands and ask, “Does the score reflect what we know? If not, why?”
Playbook library examples
Red: Stabilize and rebuild confidence
- Owner: Account Manager; Due: 3 business days
- Steps: executive outreach template; confirm top three objectives; schedule technical review; create a recovery plan with milestones and owners.
- Exit condition: two consecutive weeks back in yellow with milestone progress.
Yellow: Nudge adoption and confirm alignment
- Owner: CSM; Due: 10 business days
- Steps: identify missing onboarding steps; assign two targeted enablement modules; confirm stakeholder champions; book a check-in in 2 weeks.
- Exit condition: feature adoption up 10% week-over-week or key milestone achieved.
Green: Capture value and expand
- Owner: CSM/AE; Due: 30 days
- Steps: review usage trends; propose expansion hypothesis; schedule QBR; prepare customer story draft pending approval.
- Exit condition: QBR completed or expansion opportunity opened.
Common pitfalls and how to avoid them
- Too many inputs too soon: Start with 4–6 reliable signals; add more only if they improve predictive power.
- Lack of explainability: Always show “why” the score moved; otherwise, CS won’t trust it.
- Ignoring cohorts: Normalize within segments to avoid penalizing certain customer types.
- Alert fatigue: Rate-limit, bundle related alerts, and tie each alert to a playbook.
- Stale data: Automate daily recompute and highlight last update time.
- One-size-fits-all bands: Consider onboarding-specific thresholds and treatment.
Advanced ideas when you’re ready
- Predictive modeling: Use logistic regression on normalized inputs to fine-tune weights; keep a simple UI.
- Feature bundles: Score adoption for discrete modules and surface targeted playbooks per bundle.
- Stakeholder layer: Track sentiment and engagement by persona (economic buyer vs. champion).
- Causal checks: When a playbook runs, measure pre/post leading indicators to learn what works.
- Feedback loop: Add a CSM “override with reason” that temporarily adjusts the band; review patterns monthly.
A week-by-week plan to ship
Week 1: Define and prototype
- Pick outcomes and initial inputs.
- Sketch the dashboard and playbooks.
- Ingest a sample of the last 30 days into a staging database.
Week 2: Build the pipeline and score
- Normalize signals with cohort-aware logic.
- Compute a daily score with recency decay and overrides.
- Backfill 90 days for testing.
Week 3: Ship the dashboard and alerts
- Implement the explainable UI with top contributors.
- Create Slack/email alerts on band changes.
- Stand up initial playbooks.
Week 4: Shadow and calibrate
- Run in shadow for a subset of CSMs.
- Adjust weights/bands.
- Plan full rollout and training.
Example prompts for specific pieces
Build a cohort-aware normalization service. Inputs: plan, region, and vertical. For each input metric, compute p05 and p95 per cohort, apply log scaling and winsorization, and emit a 0–100 score per metric per account per day. The service runs nightly and is idempotent. Include metrics and an admin view of cohort baselines.
Create a "Top Contributors" computation that compares today’s health score with 7 days ago and decomposes the delta by input signals. Display a list of the top three positive and negative contributors with their numeric deltas and explanatory text.
Implement playbook templates with tasks, owners, and due dates. When a band change alert fires, instantiate the matching template, assign it to the account owner, and track progress. Provide a UI to customize templates and version them.
Make it a living system
Customer health is never “done.” Treat the score like a product:
- Quarterly reviews with CS and product to add/remove inputs.
- Versioned configuration with changelogs.
- Outcome tracking: does the score help you intervene earlier and more effectively?
With a clear model, transparent UI, and actionable playbooks, your health score becomes more than a number—it becomes an operating system for customer success. And by building it yourself on a platform like YeshBe, you keep flexibility and control as your product and motion evolve.