Every SaaS founder watches the same dashboard: MRR up and to the right, churn rate holding steady, new customer growth tracking. What they rarely see is the set of small, invisible leaks that collectively drain 8 to 15% of MRR every month, well below the threshold of any normal alerting.
These aren't the big obvious problems. Voluntary churn shows up in the cancel report. Failed payments at least hit a webhook. The leaks in this post are different — they're quiet, distributed, and rarely the top priority for anyone. Which is exactly why they persist year after year.
Here are the 7 most common MRR leaks hiding in a typical SaaS Stripe account, roughly ordered by how much they tend to cost.
1Expired cards with no preemptive notification
Every active subscription has a card, and every card has an expiration date. Somewhere between 2 and 5% of active cards expire each month. If you're not emailing customers 30 days before their card expires, roughly half of those subscriptions will fail on the first charge post-expiration and a meaningful fraction will churn before they get around to updating.
The leak: customers who would have gladly paid, lost because nobody told them their card was about to stop working.
How to find it: Query your Stripe subscriptions for cards with exp_month and exp_year in the next 30 days. Compare that list to your "expired_card" decline events from the last 6 months. The overlap is the leak.
How to plug it: A simple 30-day-out expiring card email, plus a second reminder at 7 days. Pre-dunning emails catch this before it hits the retry stage.
2Stripe Smart Retries giving up too early (or retrying wrong)
Stripe's default retry schedule is a reasonable starting point but it treats all decline codes the same. An insufficient_funds failure on day 1 gets retried on day 4 regardless of whether day 4 happens to be the customer's next payday. A processing_error (which is often transient and would succeed within minutes) waits 72 hours.
The leak: a chunk of the 30–40% of failed payments that the average SaaS never recovers are recoverable, just not with the default schedule.
How to find it: In the Stripe dashboard, filter invoices to "past_due" or "uncollectible" from the last 90 days. Look at the decline code for the first failure and the timing of the retries. Ask yourself: "Would retrying this at a different time, with knowledge of the decline code, have worked?"
How to plug it: Either tune Stripe's retry schedule in your billing settings, or layer code-aware retry logic on top. See the comparison in Stripe Smart Retries vs. custom retry logic.
3Stuck invoices in "draft" or "open" state
This one surprises people. If you've ever edited an invoice manually, tested subscriptions in your own Stripe account, or had a webhook delivery fail during a workflow, you likely have invoices sitting in draft or open state that were never finalized or collected.
In a mature Stripe account, this ranges from "a few hundred bucks" to "the price of a small car." Nobody notices because these invoices don't show up in MRR reports or failed payment alerts — they're simply not counted.
How to find it: In the Stripe dashboard, filter invoices by status = open, then sort by age. Anything older than 30 days is probably stuck.
How to plug it: Finalize and attempt collection on the legit ones; void the test/incorrect ones. Going forward, monitor for invoices that stay in draft state longer than expected — it usually indicates a webhook failure or a custom billing flow that isn't completing.
4Proration not flowing through on plan changes
When a customer upgrades mid-cycle, Stripe calculates a prorated charge for the difference. This usually works seamlessly — but when it doesn't, the customer gets the upgraded plan and you don't get the proration. Common causes: custom upgrade flows that don't specify proration_behavior, failed proration invoices that never retry, or manual plan changes via the dashboard that bypass proration entirely.
The leak is usually small per customer (tens of dollars) but the total across a year of upgrades can be surprising.
How to find it: Pull your upgrade events from the last 90 days. For each, confirm there's a corresponding successful proration charge. Gaps are leaks.
How to plug it: Audit your upgrade flow code to ensure it sets proration_behavior: 'create_prorations' (or the equivalent in your library). For manual dashboard changes, train whoever handles them to check the "prorate" box.
5Stripe Radar false positives
Stripe Radar is a net positive — it blocks fraud that would otherwise cost you in chargebacks. But it also has false positives: legitimate customers, usually in countries with lower card fraud scores or using newer card types, blocked as fraudulent when they're not.
The leak is that these customers often don't know why their charge was declined. They see "your bank declined the charge" or no error at all, and half the time they just move on.
How to find it: In Radar, filter payments blocked by risk rules or elevated risk scores over the last 90 days. Sort by amount. Eyeball the top 20 — do they look legitimate (common card types, matched billing details, consistent IPs)?
How to plug it: Tune your Radar rules. Lower the risk threshold for recurring charges on customers who've successfully paid before. For truly ambiguous cases, add a manual review queue instead of auto-blocking.
6Failed dunning emails (deliverability, not strategy)
You've set up a dunning sequence. You're sending the right copy at the right times. But what percentage of those emails are actually reaching the inbox? If you're sending transactional email from the same domain as your marketing email without proper authentication, or if your sender reputation has drifted, dunning emails go to spam — and customers don't know they need to update their card.
The leak: customers you could have saved never saw the email.
How to find it: Check your email provider's delivery stats for dunning emails specifically. Spam rates above 2% or open rates below 30% are warning signs. Also check that you have SPF, DKIM, and DMARC set up on your sending domain.
How to plug it: Send transactional email from a different subdomain than marketing (e.g., billing@billing.yourapp.com). Warm up new sending domains slowly. Monitor deliverability per email type, not just in aggregate.
7Silent downgrades you never charged for
The opposite of #4. A customer downgrades from a $99 plan to a $49 plan. Your app correctly downgrades their account. But somewhere in the flow, the charges continue at the old plan, or a coupon gets applied that shouldn't, or a free trial gets extended because a webhook handler caught the wrong event.
Usually this leak runs the other direction — underbilling rather than overbilling — because the safeguards in most SaaS billing systems err on the side of customer happiness.
How to find it: For every active subscription, compare what the customer is on in your app vs. what Stripe is billing them for. Gaps go both ways: overbilling (refund risk) and underbilling (leak).
How to plug it: A nightly reconciliation job that compares your app's "current plan" field to Stripe's active subscription plan, flagging mismatches. This also catches subscriptions that have been canceled in Stripe but are still marked active in your app (or vice versa).
How to Quantify Your Total Leak
The seven leaks above range from visible-if-you-look to nearly invisible. The only way to get a real dollar number is to look at your Stripe data directly.
The free ChurnShield Stripe Revenue Audit surfaces the first three automatically — expired cards, failed payments, and stuck invoices. The others require some custom queries, but the audit report will tell you roughly what size bucket you're in.
Rough benchmarks
As a very rough rule of thumb across the SaaS accounts we've audited: total MRR leak from these seven sources averages 8–15% of recognized MRR. Companies under $20K MRR tend to skew higher (less sophisticated billing) and companies over $500K MRR tend to skew lower (they've usually built in-house tooling). The most common single offender is #1 (expired cards), which alone accounts for 3–6% of MRR in a typical account.
Where to Start
You don't need to fix all seven. In rank order of effort-to-impact:
- Expired card emails (1–2 days of work, biggest single lever)
- Finalize stuck invoices (1 afternoon, immediate one-time recovery)
- Code-aware retry logic (1–2 weeks to build, or use a tool)
- Email deliverability audit (1 day to diagnose, variable to fix)
- Radar tuning (ongoing)
- Proration audit (1 week, then rare)
- Plan reconciliation job (1 week, then ongoing)
Most SaaS teams never get past #3 on their own, which is why ChurnShield exists — the first three fixes are what we automate end-to-end. But even if you don't use a tool for it, the leaks themselves are worth understanding. They quietly cost more than almost anything else in a subscription business.