Short answer
To calculate MRR in Stripe, sum the normalised monthly value of every active subscription: for each subscription item, multiply unit amount by quantity, divide by interval_count, convert to a monthly equivalent based on the billing interval, then apply any active discount. Exclude unpaid trials, taxes and one-off invoice items, and remove a customer only once their subscription is confirmed cancelled rather than merely past due.
What MRR means when your billing runs on Stripe
Monthly recurring revenue in a Stripe context is the normalised monthly value of every currently active subscription, calculated by combining each subscription's price, billing interval, quantity and any discounts, then summing across the customer base. Stripe does not store this number anywhere as a single field; it has to be built from the underlying subscription and invoice data.
This matters because Stripe is a billing and payments platform, not a metrics platform. It tracks individual transactions, subscription states and price changes accurately, but it leaves the interpretation of that data into a business metric like MRR to the merchant or to a third-party analytics tool such as Subscription Metric. For a general definition of the metric itself, see what is MRR.
Getting the calculation right matters beyond reporting. MRR feeds directly into churn rate, customer lifetime value, ARPU and, for many SaaS founders, a rough valuation estimate based on a multiple of annual recurring revenue. An error in the underlying MRR calculation propagates into every one of those downstream numbers.
Stripe subscription objects and where MRR data lives
A Stripe Subscription object is the starting point for any MRR calculation, and it links together the customer, one or more subscription items, and a status field that tells you whether the subscription is currently generating revenue.
The key fields worth understanding are:
- status - values include active, trialing, past_due, canceled, incomplete and unpaid. Only active and, depending on your policy, trialing subscriptions with a payment method should typically count toward current MRR.
- items - a subscription can have multiple line items, each with its own price and quantity, for example a base plan plus a metered add-on. Every item needs to be normalised and summed separately.
- discount - a nested object describing any coupon currently applied to the subscription, including percent_off or amount_off and an optional expiry date.
- current_period_start and current_period_end - the active billing cycle dates, useful for confirming a subscription is currently within a paid period rather than lapsed.
- trial_end - the timestamp a trial converts to a paid subscription, if one is set.
Each subscription item references a Price object, which is where the billing interval, currency, unit amount and, for usage-based plans, the pricing model live. To calculate MRR correctly you need to read the price alongside the subscription rather than assume a flat monthly fee.
Normalising every billing interval to a monthly figure
Billing intervals must be converted to a common monthly baseline before subscriptions can be summed, because Stripe allows prices to recur daily, weekly, monthly, every few months, or annually, and adding raw amounts across different intervals produces a meaningless total.
The commonly used conversion factors are:
| Billing interval | Conversion to monthly | Example (unit amount) |
|---|---|---|
| Monthly | Amount stays as is | 50.00 per month = 50.00 MRR |
| Annual | Amount divided by 12 | 600.00 per year = 50.00 MRR |
| Quarterly | Amount divided by 3 | 150.00 per quarter = 50.00 MRR |
| Weekly | Amount multiplied by roughly 4.33 | 11.54 per week = 50.00 MRR |
| Daily | Amount multiplied by roughly 30.44 | 1.64 per day = 50.00 MRR |
Stripe's Price object also has an interval_count field, so a price could be billed every two months or every three weeks. The general formula in plain text is: monthly equivalent equals unit amount multiplied by quantity, divided by interval_count, then converted using the interval's base factor. For a two-month billing cycle at 100 per cycle, the calculation is 100 divided by 2, giving 50.00 MRR.
Getting this normalisation wrong is one of the most common sources of error when teams build their own MRR spreadsheet directly from the Stripe API, because it is easy to treat every price as monthly by default.
A step by step worked MRR calculation
The clearest way to understand the mechanics is to walk through a small worked example using a handful of representative subscriptions, then sum the normalised values.
Assume the following active subscriptions on a Stripe account:
| Customer | Plan | Interval | Amount | Discount | Monthly equivalent |
|---|---|---|---|---|---|
| Customer A | Pro, quantity 3 seats | Monthly, 20 per seat | 60.00 | None | 60.00 |
| Customer B | Team annual | Annual, 1,200.00 | None | 100.00 | |
| Customer C | Starter | Monthly, 25.00 | 20 percent off, ongoing | 20.00 | |
| Customer D | Growth | Quarterly, 300.00 | None | 100.00 | |
| Customer E | Enterprise, trialing | Monthly, 500.00 | Not yet billed | 0.00 (excluded) |
Working through each row in plain text:
- Customer A: 20 per seat times 3 seats equals 60.00 monthly, no interval conversion needed.
- Customer B: 1,200.00 divided by 12 months equals 100.00 monthly.
- Customer C: 25.00 monthly with a 20 percent ongoing discount equals 25.00 times 0.8, which is 20.00 monthly.
- Customer D: 300.00 divided by 3 months equals 100.00 monthly.
- Customer E: still in trial with no payment collected, so it is excluded from current MRR under the common convention described in this guide.
Summing the monthly equivalents: 60.00 plus 100.00 plus 20.00 plus 100.00 equals 280.00. That figure, 280.00, is the account's total MRR for this small sample. If this account also connected a second Stripe account for a different product line with its own subscriptions, a tool like Subscription Metric would repeat the same normalisation for the second key and add the two totals together for a combined figure.
From this MRR figure, an approximate ARR is MRR times 12, so 280.00 times 12 equals 3,360.00 annually, and a simple valuation estimate at a 5x ARR multiple, as used throughout Subscription Metric, would be 3,360.00 times 5, giving 16,800.00. This is a rule of thumb rather than a formal valuation, discussed further in the section on valuation below.
How discounts and coupons change the MRR number
Coupons and discounts must be applied before a subscription's value is added to MRR, because the goal is to capture what a customer is actually paying, not the list price on the price object.
Stripe supports two main discount types on a coupon: percent_off, which reduces the amount by a percentage, and amount_off, which subtracts a fixed sum in the coupon's currency. Coupons can also be set to apply forever, for a fixed number of billing periods, or once. Each of these has a different effect on MRR over time:
- A forever coupon should be netted out of MRR for as long as the subscription exists, since the discounted price is effectively the customer's new recurring price.
- A coupon limited to a number of months should be modelled as a temporary reduction. When it expires, MRR for that customer increases back to full price, which counts as expansion revenue in that period even though the customer did not change plans.
- A once-off coupon applied to a single invoice, for example a first-month discount, arguably should not reduce ongoing MRR at all if the recurring price from the second invoice onward is the full price, though many teams still net it out for the first month for cash accuracy.
It is worth noting that Stripe coupons can be applied at the customer level or the subscription level, and a customer can in principle have more than one discount active, although this is uncommon. Any MRR calculation script or dashboard should read the discount field on the subscription object directly rather than trying to infer discounts from invoice totals, since invoice totals also include one-off items and tax.
Trials, proration and mid-cycle plan changes
Trial periods and mid-cycle changes are two of the most common reasons a naive MRR calculation drifts from reality, because both involve a subscription's economic value changing without necessarily generating a new invoice on the day of the change.
Trials
While a subscription's status is trialing and no payment has yet been collected, most practitioners exclude it from current MRR and instead track it as a separate pipeline or forecast figure. Once the trial_end date passes and Stripe successfully charges the customer, the subscription typically moves to active and its normalised value should be added to MRR from that billing period onward. Some businesses that require a card upfront and consider a trial functionally committed revenue choose to include it earlier, but this should be a deliberate, documented policy rather than an accident of how the data was queried.
Proration
When a customer upgrades or downgrades mid-cycle, Stripe by default prorates the current invoice, crediting the unused portion of the old price and charging the new price for the remainder of the period. This proration invoice amount is a one-off adjustment and should not be read as the new MRR value directly. Instead, MRR should be updated based on the subscription's new recurring price and quantity going forward, ignoring the prorated catch-up amount on the transition invoice itself.
For example, if a customer upgrades from a 50.00 monthly plan to a 100.00 monthly plan halfway through the billing period, Stripe might invoice roughly 25.00 as a prorated top-up for the remainder of the current period. MRR should not record this transaction as 25.00 of new revenue; it should immediately reflect the new steady-state value of 100.00 monthly from the point of the upgrade, since that is the ongoing recurring commitment.
Taxes, refunds and one-off charges
Tax and refunds should generally sit outside the MRR calculation because MRR is meant to represent the recurring value of the underlying subscription contract, not the exact cash that moves through the bank account in a given month.
Taxes
When Stripe Tax or a manual tax rate is applied to an invoice, the tax amount is added on top of the subscription price and collected from the customer, but it is not revenue for the business and should not be included in MRR. MRR should be calculated from the subscription's underlying price before tax, which is why reading the Price object directly, rather than the total on the most recent invoice, is the more reliable approach.
Refunds
A refund reverses cash already collected but does not, by itself, change a subscription's ongoing recurring value. If a customer is refunded for a billing error but remains an active subscriber on the same plan, MRR should be unaffected. If the refund is issued because the customer is cancelling, the churn event itself, not the refund, is what reduces MRR, and the two should be modelled as separate signals even though they often happen together.
One-off charges and invoice items
Stripe allows one-off invoice items to be added to what is otherwise a subscription invoice, for example a setup fee or a one-time overage charge. These amounts should be excluded from MRR since they do not recur automatically. Subscription Metric separates out subscription revenue from one-off payments specifically so that this distinction is visible in daily reporting rather than blended into a single number.
Failed payments and involuntary churn
A failed payment should not immediately be treated as churn, because Stripe's Smart Retries system will typically attempt to collect payment again over a period of days before giving up, and the subscription can recover without any change to the customer's plan.
The subscription status field is the reliable signal to watch. When a renewal invoice fails, the subscription usually moves to past_due while retries continue. If all retries fail and no manual recovery happens, Stripe will mark the subscription as canceled or unpaid depending on your configured subscription settings. Only at that point should the customer's normalised value be removed from MRR as churn.
This distinction matters because businesses that count every past_due subscription as immediate churn tend to understate their retained revenue and overstate their churn rate, since a meaningful share of failed payments are recovered automatically through card updates, dunning emails or retry logic. A more accurate approach separates a distinct category, sometimes called at-risk or past_due MRR, from confirmed churned MRR, and only finalises churn once Stripe's own subscription status confirms the account has actually ended.
Why Stripe's own dashboard MRR can differ from your own calculation
Stripe's dashboard MRR figure can diverge from a manual or third-party calculation because the two are not always applying identical rules to trials, discounts, multi-item subscriptions and multi-currency accounts, even though both start from the same underlying data.
Common sources of divergence include:
- Currency conversion - if a Stripe account accepts multiple currencies, the dashboard converts each subscription to the account's default currency using an exchange rate snapshot, which will not exactly match a rate applied at a different date in a custom calculation.
- Timing of updates - the built-in MRR figure can lag by up to a day, so a subscription cancelled minutes ago might still be counted at the moment you check.
- Treatment of metered and usage-based prices - since these do not have a fixed recurring amount until usage is reported, different calculation methods can estimate them differently, or exclude them entirely.
- Multiple subscription items and add-ons - a custom script that only reads the first item on a subscription will undercount accounts with add-ons or usage components layered onto a base plan.
- Included or excluded trial and past_due subscriptions - as covered above, this is a policy choice, and different tools default to different rules.
None of this means either number is wrong in an absolute sense. It means MRR is a modelled metric rather than a raw field, so the important thing for a growing business is to pick one documented methodology, apply it consistently, and use it for trend analysis rather than chasing an exact match with every other tool. Subscription Metric documents its own methodology explicitly so the figures you see are reproducible from your Stripe data at any time.
Restricted read-only keys and the permissions MRR calculation needs
A restricted API key with read-only permissions on a small set of Stripe resources is all that is required to calculate MRR, churn and related metrics safely, and it avoids granting any tool the ability to move money or change your billing configuration.
To build an accurate MRR calculation, a key generally needs read access to:
- Subscriptions, to read status, items, quantity and discount
- Prices and Products, to read unit amount, currency, interval and interval_count
- Customers, to group subscriptions and support customer-level LTV reporting
- Coupons and discounts, to apply the correct net pricing
- Invoices and Charges, to reconcile actual collected amounts, refunds and taxes
There is no need to grant write access to any of these resources, and permissions for Payouts, Balance, Account settings, Payment Links configuration or Connect platform controls can all be left at no access. This is exactly the model Subscription Metric asks for when you connect your Stripe account: a restricted, read-only key scoped to reporting data, never full account access, and never the ability to create charges, refunds or payouts on your behalf.
Creating a restricted key in Stripe takes a few minutes from the Developers section of the dashboard. Once generated, the key can be revoked instantly from the same screen if you ever want to disconnect a tool, which is a useful safety property compared with sharing a full secret key.
Building your own MRR script versus using a dedicated tool
Building a script against the Stripe API to calculate MRR is entirely possible and a reasonable starting point for a very small account, but the calculation logic grows quickly once discounts, trials, multi-currency subscriptions and usage-based pricing are all in play.
A basic version of the calculation, in plain pseudocode, looks like this: for every subscription with status active or a chosen trial policy, for every item on that subscription, take unit_amount times quantity, divide by interval_count, apply the base monthly conversion factor for the interval, then apply any active discount percentage or fixed amount, and add the result to a running total. This is a reasonable first pass, but it has to be re-tested every time your pricing model changes, for example when you add a usage-based add-on or start selling in a second currency.
A dedicated analytics layer, such as Subscription Metric, keeps this calculation logic maintained and applies it consistently across MRR movement (new, expansion, contraction, reactivation and churned MRR), churn rate, ARPU, subscriber lifetime, top customers by LTV, and a daily split of subscription versus one-off payments, all computed directly from the connected Stripe key rather than a spreadsheet snapshot. It also produces CSV, JPG and PDF exports for board decks or investor updates, and a simple 5x ARR valuation estimate calculated as MRR multiplied by 60. For teams that operate more than one Stripe account, for example separate accounts per region or product line, Subscription Metric can connect multiple restricted keys and combine them into one consolidated view rather than requiring a manual reconciliation between two dashboards.
If you are comparing options, see the broader overview at Stripe revenue analytics and the related metric definitions at the SaaS metrics glossary.
Keeping your MRR calculation accurate as the business grows
An MRR methodology that works for ten customers on a single monthly plan needs to be revisited as soon as you introduce annual billing, add-ons, multiple currencies or usage pricing, because each of these adds a new edge case that a simple sum-of-prices script will not handle correctly by default.
Practical habits that keep MRR reliable over time include:
- Documenting explicitly how trials, past_due subscriptions and coupons are treated, so anyone reading the number later understands what is and is not included.
- Recalculating MRR from live subscription data rather than from a monthly export that can go stale within days.
- Tracking MRR movement categories (new, expansion, contraction, churned, reactivated) rather than only the headline total, since the total can mask a shrinking base being offset by a few large new deals.
- Reviewing the calculation whenever pricing changes, for example when a new metered add-on or a new currency is introduced.
- Cross-checking the recurring revenue trend against net revenue retention and churn, since a healthy MRR trend combined with poor retention often signals over-reliance on new logos rather than durable growth.
If churn is trending upward, it is worth pairing the calculation work in this guide with the practical suggestions in reducing churn on Stripe, since an accurate MRR figure is most useful when it is paired with an equally accurate view of why customers are leaving.
Frequently asked questions
See these metrics for your own Stripe account
Connect a restricted read-only Stripe key and Subscription Metric computes MRR movement, churn, LTV, ARPU and a 5x ARR valuation from your live data.
Connect your Stripe key