Install any skill in seconds. Free to start, no credit card required.
Get Started Free →SaaS churn reduction covering cancel flow design, dynamic save offers, exit survey architecture, dunning sequences, payment recovery, win-back campaigns, and churn impact modeling.
.claude/skills/borghei-churn-prevention/SKILL.md| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-08 | ✗→✓ | ▲ Improved | 310% | 0% |
| case-10 | ✗→✓ | ▲ Improved | 330% | 0% |
| case-12 | ✗→✓ | ▲ Improved | 930% | 0% |
| case-05 | ✓→✗ | ▼ Worse | 364% | 0% |
| case-13 | ✓→✗ | ▼ Worse | 256% | 0% |
Production-grade SaaS churn reduction framework covering cancel flow architecture, dynamic save offer mapping, exit survey design, dunning sequence engineering, payment recovery optimization, win-back campaigns, and churn impact modeling. Addresses both voluntary churn (customers who decide to leave) and involuntary churn (customers who leave due to payment failure).
Before designing the churn-prevention system, confirm these inputs. If any is unknown or vague, ASK — do not assume:
Stop rule: ask only the 2-3 that most change the output. If the user says "just draft it," proceed and list your assumptions at the top of the deliverable.
| Question | Why It Matters | |----------|---------------| | Current monthly churn rate? (voluntary vs involuntary split) | Determines which lever to pull | | Do you have a cancel flow, or is cancellation instant/via support? | Determines build vs optimize mode | | What payment processor? (Stripe, Braintree, Paddle) | Affects dunning implementation | | Average contract value and billing cycle? | Sizes the save offer budget | | Current MRR? | Calculates the dollar impact of churn reduction | | SaaS model? (self-serve vs sales-assisted) | Determines intervention type | | Do you collect exit reasons today? | Data availability for save offer mapping |
| Type | Signal | Addressable? | |------|--------|-------------| | Value gap | Not getting enough value for the price | Yes -- save offers, feature education | | Product-market mismatch | Wrong ICP, product does not fit their use case | Partially -- downgrade or pivot | | Competitor switch | Found a better alternative | Yes -- competitive counter-offers | | Budget cut | Cannot afford it anymore | Yes -- discount or pause | | Project completion | Seasonal or project-based need | Yes -- pause option | | Poor experience | Bad support, bugs, frustration | Yes -- human intervention | | Never activated | Signed up, never used it | Partially -- reactivation before cancel |
| Cause | % of Failed Payments | Recoverable? | |-------|---------------------|-------------| | Expired card | 40-50% | Yes -- card updater service | | Insufficient funds | 20-30% | Yes -- smart retry timing | | Bank decline (fraud flag) | 10-15% | Sometimes -- customer must contact bank | | Account closed | 5-10% | No -- customer must provide new card | | Network error | 5-10% | Yes -- automatic retry |
[Cancel Button] → [Exit Survey] → [Dynamic Save Offer] → [Confirmation] → [Post-Cancel]Question: "What is the main reason you are cancelling?"
Present as radio buttons (not a dropdown). Maximum 8 options:
| Reason | Internal Code | |--------|--------------| | Too expensive for the value I get | PRICE | | Not using it enough | LOW_USAGE | | Missing a feature I need | MISSING_FEATURE | | Switching to a different product | COMPETITOR | | My project or need ended | PROJECT_END | | Too complicated to use | COMPLEXITY | | Just testing, did not plan to keep it | TESTING | | Other (with optional text field) | OTHER |
Rules:
Map each exit reason to exactly one save offer:
| Exit Reason | Save Offer | Offer Copy | |------------|-----------|------------| | PRICE | 30-50% discount for 2-3 months | "We'd like to offer you X]% off for the next N] months" | | LOW_USAGE | Pause account for 1-3 months | "Pause your account and come back when you need it" | | MISSING_FEATURE | Roadmap preview + workaround | "Feature] is coming in Q]. Here's how to achieve it now" | | COMPETITOR | Competitive comparison + discount | "Here's how we compare to competitor]. Plus X]% off" | | PROJECT_END | Pause option | "Pause instead of cancel -- your data stays safe" | | COMPLEXITY | Free onboarding session | "Let us set it up for you -- free 30-min session with our team" | | TESTING | No offer -- let them go | "Thanks for trying us out. You're welcome back anytime." | | OTHER | General retention offer | "Before you go -- we'd love to make this right. Contact support]" |
Offer presentation rules:
If they decline the save offer or there is no offer to make:
┌────────────────────────────────────────┐
│ We're sorry to see you go │
│ │
│ What happens when you cancel: │
│ - Your data is saved for 90 days │
│ - Access continues until [date] │
│ - You can reactivate anytime │
│ │
│ [Yes, Cancel My Account] │
│ [Wait, I Changed My Mind] │
│ │
│ No pre-checked boxes. │
│ No confusing language. │
└────────────────────────────────────────┘| Timing | Channel | Message | |--------|---------|---------| | Immediately | Email | Cancellation confirmation + data retention policy + reactivation link | | Day 7 | Email | "We miss you" + single CTA to reactivate + what they are missing | | Day 30 | Email | Product update + relevant improvement + reactivation offer | | Day 60 | Email | Final win-back with strongest offer (if applicable) |
Track exit survey responses monthly and calculate:
| Metric | Formula | Action Threshold | |--------|---------|-----------------| | Reason distribution | % of cancels per reason | Any reason > 30% = systemic issue | | Save rate by reason | Saved / Cancel attempts per reason | Any reason < 5% save rate = wrong offer | | Reason trend | Month-over-month change | Increasing trend = worsening problem | | Feature gap frequency | Count of "missing feature" with specific feature named | Top 3 missing features = product roadmap input |
When users select "Switching to a different product":
| Offer Type | Cost to Business | Save Rate Benchmark | When Profitable | |-----------|-----------------|---------------------|----------------| | 30% discount (3 months) | 30% of 3 months revenue | 15-25% | If LTV after save > discount cost | | 50% discount (2 months) | 50% of 2 months revenue | 20-30% | If retained customer stays 6+ months | | Pause (1-3 months) | $0 (no revenue during pause) | 25-40% | If 50%+ reactivate after pause | | Free onboarding session | CS team time (~$50-100) | 10-20% | If ARPU > $100/month | | Downgrade to lower tier | Revenue reduction | 30-50% | If some revenue > no revenue | | Feature unlock | $0 (already built) | 5-15% | Always profitable |
User selects exit reason →
├── PRICE →
│ ├── Customer ARPU > median? → Offer 30% discount
│ └── Customer ARPU < median? → Offer downgrade to cheaper plan
├── LOW_USAGE →
│ ├── Last login > 30 days? → Offer pause
│ └── Last login < 30 days? → Offer usage tips + discount
├── MISSING_FEATURE →
│ ├── Feature on roadmap? → Share roadmap + workaround
│ └── Feature not planned? → Offer discount or acknowledge gap
├── COMPETITOR →
│ ├── Known competitor? → Show comparison + retention offer
│ └── Unknown competitor? → General retention offer
├── PROJECT_END →
│ └── Always → Offer pause
├── COMPLEXITY →
│ ├── Enterprise/high-value? → Offer dedicated onboarding session
│ └── SMB/low-value? → Offer guided tutorial link
└── TESTING →
└── Always → No offer, let go gracefullyFailed payments cause 20-40% of total churn. Most of it is recoverable with proper dunning.
Do not retry immediately after failure. Cards often recover within 3-7 days.
| Retry | Timing | Why This Timing | |-------|--------|-----------------| | Initial charge | Day 0 | Normal billing cycle | | Retry 1 | Day 3 | Most card issues resolve within 72 hours | | Retry 2 | Day 7 | Paycheck cycle alignment | | Retry 3 | Day 12 | Second paycheck cycle | | Retry 4 | Day 18 | Final attempt before service action | | Service action | Day 21 | Downgrade or cancel |
Enable automatic card updating to prevent expired card churn:
| Processor | Service | How to Enable | |-----------|---------|---------------| | Stripe | Automatic card updates | Enabled by default on most plans | | Braintree | Account Updater | Must enable in merchant settings | | Paddle | Built-in | Automatic | | Recurly | Account Updater | Configuration required |
| Day | Subject Line | Body Focus | CTA | |-----|-------------|-----------|-----| | 0 | "Your Product] payment didn't go through" | Factual, no blame. Card may be expired or funds unavailable. | Update Payment Method] | | 3 | "Action needed: update your payment for Product]" | Remind what they will lose access to. | Update Payment Method] | | 7 | "Your Product] account is at risk" | List features/data they have created. Mild urgency. | Update Payment Method] | | 14 | "Final notice: your Product] access ends in 7 days" | Clear deadline. Offer to help if bank issue. | Update Payment Method] + Contact Support] | | 21 | "Your Product] account has been paused" | Account status change. Data is safe. Easy reactivation. | Reactivate Account] |
Email rules:
| Window | Success Rate | Approach | |--------|-------------|---------| | Day 7 post-cancel | 5-10% | Gentle reminder, no pressure | | Day 30 post-cancel | 3-7% | Product update + offer | | Day 60 post-cancel | 2-5% | Strongest offer + fresh start | | Day 90+ post-cancel | 1-3% | Major product change only |
Day 7 Email:
Day 30 Email:
Day 60 Email:
| Signal | Weight | Detection | |--------|--------|-----------| | Login frequency declining (week over week) | High | Usage analytics | | Feature usage dropping | High | Feature event tracking | | Support ticket escalation | High | Help desk data | | NPS response < 7 | High | Survey data | | Invoice dispute or payment question | Medium | Billing system | | Champion left the company | High | Contact monitoring | | Contract renewal in < 90 days | Medium | CRM data | | Competitor evaluation detected | High | Sales intelligence |
Risk Score = Sum of (Signal Weight x Signal Present)
0-20: Low risk (monitor)
21-40: Moderate risk (proactive outreach)
41-60: High risk (intervention required)
61+: Critical risk (executive escalation)| Metric | Formula | Good | Excellent | |--------|---------|------|-----------| | Save rate | Customers saved / Cancel attempts | 10-15% | 20%+ | | Voluntary churn rate | Voluntary cancels / Total customers (monthly) | < 3% | < 1.5% | | Involuntary churn rate | Failed payment cancels / Total customers (monthly) | < 1.5% | < 0.5% | | Payment recovery rate | Failed payments recovered / Total failed | 25-35% | 40%+ | | Win-back rate | Reactivations / Cancellations (90-day window) | 5-10% | 10%+ | | Exit survey completion rate | Surveys completed / Cancel attempts | > 70% | > 90% | | Save offer acceptance rate | Offers accepted / Offers shown | 15-25% | 30%+ |
| Signal | Diagnosis | Action | |--------|-----------|--------| | Save rate < 5% | Offers not matching reasons | Rebuild offer-reason mapping | | Exit survey completion < 60% | Survey too long or optional | Make it required, 1 question | | Recovery rate < 20% | Retry logic or emails broken | Audit dunning sequence | | Single reason > 40% | Systemic product/pricing issue | Escalate to product/leadership | | Churn rate > 5% monthly | Business is likely contracting | Churn prevention alone will not fix; review ICP + product |
Monthly MRR at risk = Total MRR x Monthly churn rate
Annual MRR saved by 1% churn reduction = Total MRR x 0.01 x 12
Annual MRR saved by 20% save rate = (Monthly MRR at risk x 0.20) x 12
Example:
MRR: $500,000
Monthly churn: 4% = $20,000/month lost
Reduce to 3% = $5,000/month saved = $60,000/year
Add 20% save rate on remaining = $3,000/month saved = $36,000/year
Total annual impact: $96,000| Artifact | Format | Description | |----------|--------|-------------| | Cancel Flow Design | 5-stage flow with copy | Complete flow from trigger to post-cancel | | Exit Survey | Radio button options + mapping | 6-8 reasons with save offer mapping | | Save Offer System | Decision tree | Reason-to-offer mapping with economics | | Dunning Sequence | 5-email sequence | Subject lines, body copy, timing, retry schedule | | Win-Back Campaign | 3-email sequence | Day 7, 30, 60 emails with subject lines and offers | | Churn Scorecard | Metric table | Current metrics vs benchmarks with gap analysis | | Impact Model | Revenue calculation | Dollar impact of churn reduction at various improvement levels |
Purpose: Calculate the revenue impact of churn reduction at various improvement levels.
bashpython scripts/churn_impact_calculator.py --mrr 500000 --churn-rate 4.0 --save-rate 20 python scripts/churn_impact_calculator.py --mrr 500000 --churn-rate 4.0 --save-rate 20 --json
| Flag | Required | Description | |------|----------|-------------| | --mrr | Yes | Current monthly recurring revenue in dollars | | --churn-rate | Yes | Current monthly churn rate as percentage (e.g., 4.0 for 4%) | | --save-rate | No | Cancel flow save rate as percentage (default: 15) | | --target-churn | No | Target churn rate as percentage (default: current minus 1) | | --json | No | Output results as JSON |
Purpose: Analyze dunning email sequence effectiveness and recommend retry timing optimizations.
bashpython scripts/dunning_sequence_analyzer.py dunning_data.json python scripts/dunning_sequence_analyzer.py dunning_data.json --json
| Flag | Required | Description | |------|----------|-------------| | dunning_data.json | Yes | JSON file with failed payment and retry data | | --json | No | Output results as JSON |
Input JSON format:
json{ "failed_payments": [ { "payment_id": "PAY-001", "amount": 99.00, "failure_reason": "expired_card", "retry_attempts": [ {"day": 0, "recovered": false}, {"day": 3, "recovered": false}, {"day": 7, "recovered": true} ] } ] }
Purpose: Analyze exit survey responses to identify churn patterns, save offer effectiveness, and systemic issues.
bashpython scripts/exit_survey_analyzer.py survey_data.json python scripts/exit_survey_analyzer.py survey_data.json --json
| Flag | Required | Description | |------|----------|-------------| | survey_data.json | Yes | JSON file with exit survey response data | | --json | No | Output results as JSON | | --period | No | Analysis period label (default: "current") |
| Problem | Likely Cause | Solution | |---------|-------------|----------| | Save rate below 5% across all reasons | Save offers do not match exit reasons | Rebuild the exit-reason-to-offer mapping using survey data; run exit_survey_analyzer.py to identify mismatches | | Exit survey completion under 60% | Survey is optional or too long | Make the single-question survey required before showing the save offer; remove multi-page flows | | Payment recovery rate below 20% | Retry logic misconfigured or dunning emails not sending | Audit dunning sequence with dunning_sequence_analyzer.py; verify email deliverability and retry schedule | | Single exit reason exceeds 40% of responses | Systemic product or pricing issue | Escalate to product or leadership; this is not solvable with cancel flow alone | | Churn rate above 5% monthly | Likely ICP, product-market fit, or pricing problem | Churn prevention alone will not fix this; pair with pricing-strategy and product feedback loops | | Win-back emails have zero reactivations | Emails not reaching inbox or offers are weak | Check deliverability (SPF, DKIM, DMARC); test stronger offers; verify reactivation links work | | Involuntary churn rising while voluntary is stable | Card updater not enabled or retry timing is poor | Enable automatic card updating on your payment processor; review retry schedule in dunning_sequence_analyzer.py |
| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-18 | pass→pass | 8,904 | 11,073 | +24% | 1 | 1 | 0% | 1,466 | 7,455 | +409% | 0 | 0 | — |
case-19 | pass→pass | 12,556 | 17,979 | +43% | 1 | 1 | 0% | 1,858 | 8,488 | +357% | 0 | 0 | — |
case-01 | pass→pass | 20,246 | 28,312 | +40% | 1 | 1 | 0% | 3,370 | 10,524 | +212% | 0 | 0 | — |
case-02 | pass→pass | 30,532 | 39,103 | +28% | 1 | 1 | 0% | 4,853 | 11,930 | +146% | 0 | 0 | — |
case-03 | pass→pass | 30,541 | 37,415 | +23% | 1 | 1 | 0% | 5,405 | 11,931 | +121% | 0 | 0 | — |
case-04 | pass→pass | 11,497 | 15,615 | +36% | 1 | 1 | 0% | 1,814 | 8,431 | +365% | 0 | 0 | — |
case-05 | pass→fail | 11,734 | 19,651 | +67% | 1 | 1 | 0% | 1,915 | 8,893 | +364% | 0 | 0 | — |
case-06 | pass→pass | 9,129 | 8,091 | -11% | 1 | 1 | 0% | 1,339 | 6,957 | +420% | 0 | 0 | — |
case-07 | fail→fail | 12,007 | 11,482 | -4% | 1 | 1 | 0% | 1,969 | 7,457 | +279% | 0 | 0 | — |
case-08 | fail→pass | 11,711 | 11,367 | -3% | 1 | 1 | 0% | 1,814 | 7,442 | +310% | 0 | 0 | — |
case-09 | pass→pass | 14,421 | 15,215 | +6% | 1 | 1 | 0% | 2,180 | 8,010 | +267% | 0 | 0 | — |
case-10 | fail→pass | 12,076 | 13,934 | +15% | 1 | 1 | 0% | 1,853 | 7,975 | +330% | 0 | 0 | — |
case-11 | pass→pass | 9,662 | 12,194 | +26% | 1 | 1 | 0% | 1,565 | 7,749 | +395% | 0 | 0 | — |
case-12 | fail→pass | 4,901 | 12,161 | +148% | 1 | 1 | 0% | 768 | 7,913 | +930% | 0 | 0 | — |
case-13 | pass→fail | 13,602 | 11,989 | -12% | 1 | 1 | 0% | 2,145 | 7,626 | +256% | 0 | 0 | — |
case-14 | pass→pass | 14,236 | 11,052 | -22% | 1 | 1 | 0% | 2,149 | 7,438 | +246% | 0 | 0 | — |
case-15 | pass→pass | 10,698 | 12,374 | +16% | 1 | 1 | 0% | 1,664 | 7,665 | +361% | 0 | 0 | — |
case-16 | pass→pass | 8,643 | 11,508 | +33% | 1 | 1 | 0% | 1,338 | 7,446 | +457% | 0 | 0 | — |
case-17 | pass→pass | 11,260 | 12,349 | +10% | 1 | 1 | 0% | 1,635 | 7,561 | +362% | 0 | 0 | — |
case-20 | fail→fail | 17,838 | 30,152 | +69% | 1 | 1 | 0% | 2,612 | 10,419 | +299% | 0 | 0 | — |
case-21 | fail→fail | 19,424 | 25,274 | +30% | 1 | 1 | 0% | 3,085 | 9,764 | +216% | 0 | 0 | — |
case-22 | fail→fail | 19,122 | 22,692 | +19% | 1 | 1 | 0% | 2,976 | 9,625 | +223% | 0 | 0 | — |
DecimalAI ran this skill against gemini-3.6-flash twice over the same eval suite — once with the skill loaded and once without — and compared the two runs case by case. 22 cases were attempted. The headline lift of +5 percentage points is the difference between those two pass rates over the 22 comparable cases. 2 cases got worse with the skill loaded, and they are included in that figure.
Without the skill loaded, the model failed this case. With it loaded, the same prompt on the same model passed. This is one improved case from the latest verified run; every case, including any that regressed, is in the table above.
Other measured skills in the registry, with their headline benchmark lift.