Revenue leakage is money your business earned on paper but never collected in practice. It's not theft. It's not a billing bug. It's the structural gap between what your CRM says happened and what your bank account confirms. Gartner estimates typical B2B revenue leakage at 3-8% of total revenue. Clari's research puts it in the same range. At $5M ARR, that's $150,000-$400,000 per year — enough to fund two engineers or an entire marketing budget — quietly disappearing between systems.
The frustrating thing is that nobody is lying. HubSpot correctly records what the sales team entered. Stripe correctly bills what was configured. The leak exists in the space between them — in handoffs nobody is monitoring, in timing gaps nobody notices, in identity mismatches nobody resolves.
Here are the seven patterns I see most often, roughly ordered by how much money they typically represent.
1. Won-but-unpaid deals
What it is: A deal moves to "Closed Won" in your CRM but no subscription or invoice is ever created in Stripe (or whatever billing system you use).
Why it happens: The handoff from sales to billing isn't automated. An AE closes a deal, updates the CRM, and moves on. Billing setup requires a separate action — creating the subscription, sending the first invoice, or triggering an onboarding workflow that includes payment collection. If that action gets dropped, the CRM celebrates revenue that was never real.
Typical magnitude: 2-5% of closed-won deals at companies without automated billing setup. Higher for companies with custom enterprise pricing that requires manual subscription creation.
How to detect it:
SELECT d.deal_name, d.amount, d.close_date
FROM crm_deals d
LEFT JOIN billing_subscriptions s
ON d.contact_email = s.customer_email
AND s.created_at > d.close_date - INTERVAL '7 days'
WHERE d.stage = 'closed_won'
AND d.close_date < CURRENT_DATE - INTERVAL '14 days'
AND s.id IS NULL;How to fix it: Automate the deal-to-subscription handoff. When a deal hits closed-won, trigger subscription creation programmatically. If your deal structure is too complex for full automation, at minimum create an alert that fires if no subscription appears within N days of close.
2. Silent churn (zombie subscriptions)
What it is: A customer is still paying (subscription active, payments succeeding) but hasn't used the product in 30+ days. They're already gone — you just haven't been told yet.
Why it happens: SaaS companies track churn as "subscription canceled." But cancellation is the last step. A customer stops using the product weeks or months before they cancel. During that gap, you're collecting revenue from a relationship that's already over. When they finally cancel, it's too late to save them.
Typical magnitude: 15-25% of eventual churns show zero product usage for 30+ days before cancellation. If your monthly churn is 5%, roughly 1% of your customer base is in "zombie" state at any given time.
How to detect it:
SELECT
s.customer_email,
s.plan_name,
s.monthly_amount,
MAX(e.event_date) AS last_active_date,
CURRENT_DATE - MAX(e.event_date) AS days_inactive
FROM billing_subscriptions s
LEFT JOIN product_events e
ON s.customer_id = e.user_id
AND e.event_date > CURRENT_DATE - INTERVAL '90 days'
WHERE s.status = 'active'
GROUP BY s.customer_email, s.plan_name, s.monthly_amount
HAVING MAX(e.event_date) < CURRENT_DATE - INTERVAL '30 days'
OR MAX(e.event_date) IS NULL
ORDER BY s.monthly_amount DESC;How to fix it: Build a "health score" that combines payment status + product usage. When usage drops to zero but payment continues, trigger a CS intervention: check-in email, success call, or in-app message. The goal isn't to prevent the eventual churn (some of these customers are genuinely done) — it's to either save the ones who forgot about you or accelerate the ones who are leaving so you can reallocate CSM bandwidth.
3. Failed payment cascades (involuntary churn)
What it is: A customer's payment method fails — expired card, insufficient funds, bank decline. Stripe retries over 3-4 weeks. All retries fail. The subscription cancels. You've now involuntarily churned a customer who might have stayed if someone had asked them to update their card.
Why it happens: Stripe's default dunning is 4 retry attempts over ~23 days, then cancel. That's reasonable as a default, but it's entirely automated with no human touch. If nobody at your company is watching failed payments, you're relying on Stripe's generic retry schedule and automated emails (which many customers never see or ignore).
Typical magnitude: Involuntary churn accounts for 20-40% of total churn at most SaaS companies. The Recurly Research team puts the recovery rate for smart dunning at 70%+ when done well, versus 50% for Stripe's default retry logic.
How to detect it:
SELECT
c.email,
s.plan_name,
s.monthly_amount,
i.attempt_count,
i.next_retry_date,
i.amount_due
FROM billing_invoices i
JOIN billing_subscriptions s ON i.subscription_id = s.id
JOIN billing_customers c ON s.customer_id = c.id
WHERE i.status = 'open'
AND i.attempt_count >= 2
AND s.status = 'past_due'
ORDER BY i.amount_due DESC;How to fix it: Layer human outreach on top of automated retries. After the second failed attempt, have CS reach out directly: "Hey, looks like your payment didn't go through — mind updating your card?" This single intervention can cut involuntary churn by 30-50%. Also: surface these in real time so someone sees them before the retry window exhausts.
4. Pricing drift (upgrades/downgrades not reflected)
What it is: A customer's actual billing amount in Stripe doesn't match what your CRM records as their deal value. Maybe they upgraded but the CRM deal was never updated. Maybe they negotiated a discount that only exists in Stripe. Maybe they're on a grandfathered plan that nobody's tracked.
Why it happens: CRM deal amounts are set at close time and rarely updated. Stripe amounts change with every plan change, proration, and add-on. Without a continuous sync, the two systems drift apart immediately after close and never re-converge.
Typical magnitude: After 12 months, 30-50% of customer records show a discrepancy between CRM deal value and Stripe actual MRR. The median drift is 10-15% — enough to make your CRM revenue report unreliable.
How to detect it:
SELECT
d.deal_name,
d.amount AS crm_annual_value,
s.monthly_amount * 12 AS stripe_annual_value,
d.amount - (s.monthly_amount * 12) AS drift,
ABS(d.amount - (s.monthly_amount * 12)) / d.amount * 100 AS drift_pct
FROM crm_deals d
JOIN billing_subscriptions s
ON d.contact_email = s.customer_email
WHERE d.stage = 'closed_won'
AND s.status = 'active'
AND ABS(d.amount - (s.monthly_amount * 12)) > 100
ORDER BY ABS(drift) DESC;How to fix it: Sync Stripe subscription amounts back to the CRM continuously. Either write a webhook that updates the deal/contact properties on every subscription.updated event, or run a nightly reconciliation that flags drifts above a threshold.
5. Marketing attribution gaps
What it is: Marketing reports that a campaign generated $200k in pipeline. The CRM confirms it: 8 deals sourced from that campaign, marked closed-won, totaling $200k. But when you check Stripe, only $140k was ever collected from those customers. $60k was either never invoiced, canceled before first payment, or attributed to the wrong source.
Why it happens: Marketing attribution stops at the CRM. Once a deal is marked closed-won with a source attribution, marketing's job is "done." Nobody goes back to verify that attributed revenue actually became real revenue. The feedback loop is broken at the moment of attribution.
Typical magnitude: 15-30% of marketing-attributed revenue doesn't survive the journey from CRM to billing. This means marketing is optimizing spend against inflated numbers.
How to fix it: Close the attribution loop by joining marketing source data → CRM deal data → billing collection data. Report on "collected revenue by channel," not just "closed-won revenue by channel." This is a harder number to game and a better signal for channel allocation.
6. Discount and coupon leakage
What it is: Sales promises a discount ("first 3 months at 50% off") that gets configured in Stripe but never expires. Or a promotional coupon that was supposed to be limited-use gets shared and applied indefinitely. Or a discount is applied to one customer and accidentally propagated to their team subscription.
Why it happens: Discounts are configured in billing systems but tracked in CRMs as text notes. Nobody is systematically comparing what was promised (the CRM note or contract) against what's actually being charged (the Stripe coupon). Stripe's coupon system doesn't enforce organizational policies — it applies whatever it's told.
Typical magnitude: 1-3% of revenue at companies that regularly offer discounts. Higher at companies with aggressive enterprise discounting and poor coupon hygiene.
How to fix it: Run a monthly report of all active coupons/discounts in Stripe, their creation date, and their expected expiry. Flag any discount running longer than its intended duration. Implement a policy that all discounts have an end date — no perpetual coupons.
7. Expansion revenue not captured
What it is: A customer's usage grows beyond their plan limits. They should be on a higher tier or paying overage charges. But the billing system isn't configured to enforce limits or charge overages, so they continue on the same plan at the same price while consuming 3x the resources.
Why it happens: Usage-based billing is hard to implement. Many companies set plan limits as soft limits (documented but not enforced) and rely on CSMs to notice when a customer outgrows their plan and initiate an upsell conversation. That works at 50 customers. At 500, it falls apart.
Typical magnitude: Highly variable. Companies with usage-based components can see 5-10% of potential expansion revenue never captured because nobody noticed the customer exceeded their tier threshold.
How to fix it: Implement automated usage threshold alerts. When a customer hits 80% of their plan limit, alert the CSM. When they exceed 100%, either enforce (downgrade their experience) or alert for upsell. Either way, don't let it go unnoticed.
The compounding problem
Revenue leakage compounds. A 5% leak rate doesn't mean you lose 5% once — it means every cohort of new customers starts leaking from day one, and the cumulative effect grows over time as your customer base grows. At $1M ARR, a 5% leak is $50k/year. Annoying but survivable. At $10M ARR, it's $500k/year. At $50M, it's $2.5M. The same percentage becomes an increasingly unacceptable absolute number, and by the time it hurts enough to fix, you've accumulated years of leaked revenue that's unrecoverable.
The detection stack
Most companies discover leaks through one of these three methods:
Manual reconciliation — someone in Finance pulls Stripe data and CRM data into a spreadsheet every quarter and looks for discrepancies. Catches problems 30-90 days late. Labor-intensive. Usually the first thing that gets skipped when the team is busy.
Scheduled SQL reports — a recurring query in your warehouse that flags mismatches and sends results to Slack or email. Catches problems within 1-7 days depending on schedule. Requires maintaining queries as schemas evolve. Better than manual, but still reactive.
Real-time cross-source monitoring — a system that continuously joins billing and CRM data and fires alerts the moment a mismatch appears. Catches problems within minutes. This is what Fastero's revenue leak detection does — it connects to Stripe and HubSpot (or Salesforce), runs reconciliation queries continuously, and alerts you in Slack when any of the seven patterns above appear.
The right answer depends on your scale. At $500K ARR, a quarterly spreadsheet is fine. At $2M, you need scheduled queries. At $5M+, the cost of delayed detection exceeds the cost of real-time monitoring tooling. Pick the level that matches your current pain.
Related reading:
- How to Detect Revenue Leaks Between CRM and Billing — the operational detection guide
- 12 SQL Queries for CRM-to-Billing Reconciliation — copy-paste queries for each leak type
- How to Reconcile Stripe Revenue with Your CRM — building reconciliation from scratch
- How to Find Won-but-Unpaid Deals in HubSpot — deep dive on leak #1
- Automate Won-but-Unpaid Deal Detection — HubSpot workflows + code
- Detect and Recover Failed Stripe Payments — deep dive on leak #3
- Silent Churn Detection — deep dive on leak #2
- Best Revenue Leak Detection Tools 2026 — 8 tools compared
- How to Calculate Real MRR from Stripe — get the numbers right first
- Sync Stripe to HubSpot with Python — the integration foundation
Try Fastero free — connect your CRM and billing data, get live revenue dashboards, and set up alerts that catch leaks before your next board meeting. No credit card required.
Last updated: July 2026.

