Why your Stripe MRR is wrong — and Stripe will never tell you
September 7, 2026
At some point you pulled up the MRR number in your Stripe dashboard, quoted it in a board deck, an investor update, or a Slack message to your co-founder, and moved on with your day. Most of the time that number is close enough. Some of the time it is quietly, structurally wrong — not because of a bug in Stripe, but because “monthly recurring revenue” is a modeling decision, and Stripe’s default model makes several choices that don’t match how most businesses actually think about revenue. None of these show up as an error. All of them look, from inside the dashboard, exactly like a correct number.
This isn’t a criticism of Stripe’s reporting — it’s a genuinely hard problem to solve generically for every business model on the platform. But if you’ve ever looked at the number and thought “that doesn’t look right” and then talked yourself out of the feeling, this is the list of specific, checkable reasons you might have been correct the first time.
1. Annual plans get squashed into a single month, then vanish for eleven
Stripe’s MRR calculation recognizes an annual subscription’s value in the month it renews, not spread evenly across the year. A customer paying $1,200/year shows up as a $1,200 spike in MRR the month they pay, then contributes roughly nothing for the following eleven months. If your business has a meaningful mix of monthly and annual plans, your MRR chart isn’t a smooth line reflecting steady recurring revenue — it’s a series of spikes that happen to land wherever your annual renewals land. A month with three annual renewals looks like explosive growth. The following month, with none, looks like a cliff. Neither is real; both are artifacts of when the calendar happened to place a renewal.
2. “Past due” still counts as active revenue
When a renewal payment fails, Stripe doesn’t immediately drop the subscription — it moves to past_due and enters your dunning retry schedule, which can run anywhere from a few days to several weeks depending on your settings. Stripe’s MRR figure, by default, still counts a past_due subscription as contributing revenue, because technically it hasn’t been canceled. You can be carrying weeks of MRR from customers whose card has been declining since the first retry attempt, reporting it as healthy revenue the entire time, with the actual cash never landing in your account.
3. Coupons and discounts distort the number in whichever direction hurts you
A subscription with a 50%-off coupon applied is either counted at full price (overstating what you actually collect) or at the discounted price if Stripe correctly applies the coupon to the reported figure — and which one happens depends on coupon type, duration, and whether it’s a percentage or fixed amount off, in ways that aren’t always obvious from the dashboard alone. Run a seasonal promotion, a lifetime deal, or founder-friend discounts, and your MRR chart can either spike (if discounts are undercounted) or dip (if they’re overcounted) in a way that has nothing to do with actual customer growth.
4. Multi-currency conversion happens at report time, not payment time
If you charge in multiple currencies, Stripe converts everything to your reporting currency using a current exchange rate for the summary figure — not the rate that was actually in effect when each customer paid. A batch of EUR or GBP subscriptions can make your MRR appear to grow or shrink between one dashboard refresh and the next with zero customer activity, purely because the exchange rate moved. If you’re presenting MRR trend data to anyone who’s going to make a decision based on the slope of the line, an unannounced FX-driven wobble is exactly the kind of thing that triggers a confused, wrong conclusion.
5. Plan changes mid-cycle create proration entries that look like separate revenue events
A customer upgrading from a $29 to $99 plan halfway through their billing cycle generates a prorated invoice item for the difference — a real, correct charge. But depending on how your reporting aggregates invoice line items versus subscription-level MRR, that proration can either get double counted alongside the new plan’s full value, or dropped entirely if your calculation only looks at the subscription’s current price and misses the one-time catch-up charge. Neither failure mode is rare once a product has more than one or two pricing tiers and any meaningful rate of customers moving between them.
invoice.payment_succeeded event for that month directly from Stripe’s own event log or the Payments report, in whatever currency they actually settled in. Compare that number — cash that actually arrived — to what your MRR dashboard reported for the same period. A gap of a few percent is normal rounding. A gap in the double digits means one or more of the five causes above is live in your account right now.Why this is worse than a reporting inconvenience
A wrong MRR number doesn’t just make a slide look slightly off. It’s the input to decisions that compound: how much runway you think you have, what growth rate you tell investors, whether a marketing channel gets more budget because it appears to be driving revenue it isn’t, whether you raise a round on a trajectory that a careful diligence process will eventually reprice downward once someone reconciles the number against actual bank deposits. The failure mode isn’t a single bad month — it’s a persistent, structural bias that makes every trend line you look at slightly (or significantly) misleading in a consistent direction, which is exactly the kind of error that’s hardest to catch by eyeballing a chart, because a consistently biased number still looks smooth and trustworthy.
What actually fixes it
- Normalize annual plans yourself. Divide annual subscription value by 12 and recognize it monthly, rather than trusting Stripe’s renewal-month spike. This alone fixes the most visually dramatic distortion for any business with mixed billing intervals.
- Exclude
past_dueandunpaidsubscriptions from your MRR figure, not just from your churn figure. If the money hasn’t actually been collected, it isn’t recurring revenue yet — it’s a receivable, and reporting it as the same thing as collected cash overstates the business’s health during exactly the period when you most need an accurate read. - Compute discounted value directly from each subscription’s actual line items, not from the plan’s list price, so coupons and one-off discounts flow through correctly in both directions.
- Lock currency conversion to the rate at time of transaction for historical trend data, and only use a live rate for a real-time snapshot — never mix the two in the same chart.
- Reconcile monthly against actual settled payments, not against the subscription object’s theoretical price. The subscription tells you what’s supposed to happen; the invoice and payment history tell you what did.
A number you can trust is worth building once
None of the five causes above are edge cases — they’re default Stripe behavior that every business on the platform inherits the moment they have more than a single flat monthly plan, any failed payments, or any customers outside your home currency. Which, in practice, is almost every SaaS company past its first few months. The fix isn’t switching platforms or fighting Stripe — it’s treating the subscription and invoice data as the source of truth and building your own recognition logic on top of it, once, instead of re-trusting a dashboard number that was never built to model your specific business.
What we built this for
Revenue reporting is only half the problem — the other half is access. I built Venwai after running into the access side of this same gap: Stripe says a customer is paying, but the app never granted them access (see this one), or a subscription quietly stops being paid without the delete event ever firing (see this one). Venwai connects to Stripe with a read-only key, polls a single endpoint you expose on your own app once a day, and diffs who Stripe says is paying against who your app says has access — alerting you the moment they disagree, in Slack, Discord, Telegram, or email.
Free while it’s in beta, no card required: venwai.com.