How to Turn a Subscription Export Into an MRR and ARR Report (2026 Guide)

A subscription export gives you rows: customer, plan, amount, interval, status, start date. An MRR report needs one number per month. Getting from one to the other looks like arithmetic and is mostly definitions.
Two choices decide every figure in the finished report. Which subscriptions count as active, and whether discounts come off the amount.
Get either wrong and the report still balances internally. It just disagrees with finance, with the billing dashboard, and with last month's version.
This guide covers what to settle first, the three manual routes, and where each one stops working.
What you need before you start
You need the export with one row per subscription, not one row per invoice. Invoices tell you what was billed. Subscriptions tell you what recurs.
You need the billing interval on every row. Monthly and annual plans cannot be summed until the annual ones are normalised.
You also need the status column. Stripe's billing analytics documentation defines MRR as a sum of monthly-normalised amounts. It counts only the subscriptions with status active and past_due.
That definition is worth adopting as-is. It is published, it is specific, and it gives you a defensible answer when someone asks why a number moved.
Three decisions come first.
Which statuses count. Active plus past due is the documented default. Canceled and unpaid are treated as churn and drop out.
Whether discounts come off. Stripe makes this configurable, with separate settings for recurring and one-time discounts. Forever discounts are always deducted.
When a subscriber starts counting. Stripe lets you choose the start of the first billing period or the receipt of the first payment. The first option is described as the most common.
Write those three on the sheet before you write a formula. They are the difference between a report and an argument.
Why the arithmetic is the easy part
Normalising is simple. Stripe's own worked example uses 100 subscribers on a $100 monthly plan plus 50 on a $600 annual plan. That gives (100 × 100) + (50 × (600 / 12)) = 12,500.
The complications are the exclusions, and they are easy to miss in a spreadsheet.
Taxes are out. Stripe excludes tax from MRR. If your export carries gross amounts, you are overstating every month.
Trials are out. Subscriptions in a trial period are excluded until they convert.
Free plans are out. A subscriber on a zero-price plan contributes nothing, so they are not counted as an active subscriber either.
Usage-based revenue is out. This is the one that surprises people. Metered products are excluded from MRR entirely, so a partly usage-billed business will see MRR sit below actual revenue by design.
Then there is the coupon case, which is documented and genuinely counter-intuitive. If a subscriber's MRR falls to zero, that subscriber is treated as churned for the period.
A 100% off coupon does exactly that. Remove the coupon later and the subscriber becomes active again, which shows up as a reactivation.
So a promotion can produce churn in your report without a single customer leaving.
How to do it manually
Option 1: Normalise the interval, then sum by month
Add a monthly amount column. Divide annual amounts by twelve, multiply weekly by roughly 4.33, and leave monthly alone.
Then total by month with SUMIFS, filtering on status. Use EOMONTH to build the month-end dates you are reporting against.
Report MRR as of a month end, not as of today. Stripe's downloadable report is explicitly the MRR of each subscriber at month end, and matching that convention saves reconciliation later.
The ceiling here is history. This gives you the current month cleanly and tells you nothing about why it changed.
Option 2: Build the movement columns
This is what makes the report useful. Break the change into new, reactivation, expansion, contraction and churn.
Stripe's growth definition is the starting figure plus new, reactivation and expansion, minus contraction and churn, then adjusted for exchange rates. Its worked example moves $1,000 to $1,045 through exactly those components.
Note the last term. If any customer pays in another currency, a pure formula model will not reconcile until you handle the exchange effect.
Multi-currency has a second consequence worth knowing. Stripe states that filtering and grouping by product or price is unavailable when subscription revenue is handled in several currencies.
The limit of this route is maintenance. Movement columns need a prior-period snapshot, so you are keeping a second copy of last month forever.
Option 3: Take the movements from the billing system instead
Most billing platforms will export the movements for you. Stripe publishes three CSVs: MRR per subscriber by month, a subscription metrics summary, and a log of every customer MRR movement.
That third file is the one to ask for. It removes the hardest part of Option 2.
If you do change a metric definition, expect a delay. Stripe notes that configuration changes take 24 to 48 hours to appear.
The shared ceiling. All three routes stop at MRR. Turning it into ARR, ARPU, churn and retention means another layer of decisions on top of the same table.
Where the manual route slows down
The first month takes an afternoon. The fourth takes longer, and not because the data got harder.
By then the workbook holds two definitions of active, a hand-patched exchange column, and a movement tab nobody wants to touch.
Derived metrics multiply the problem. ARPU is total MRR divided by active subscribers. Lifetime value is ARPU divided by the churn rate.
Churn has its own trap. Stripe's denominator is the subscribers active thirty days ago plus the new subscribers added in that window, which gives 100 / (1000 + 100) = 9.1%. A spreadsheet that divides by the opening count alone reports a higher number.
Retention behaves unexpectedly too. Revenue retention can exceed 100%, because expansion inside a cohort outweighs churn.
None of this is hard. It is just five judgement calls that have to be made identically every month, by whoever happens to be building the report.
How to build the report with Powerdrill Bloom
Step 1: Upload your subscription export
Upload the subscription CSV, or the subscription and movement files together. Powerdrill Bloom profiles the columns on arrival, so missing intervals, blank amounts and duplicated subscription IDs surface before any total is computed.
Step 2: State the definitions in natural language
Describe the rules rather than building them. Say which statuses count, whether amounts are net of discounts, and which month end you are reporting.
Then ask for the checks in the same pass. Ask which rows have an interval you did not expect, and which subscriptions sit at zero after discounts. Then ask whether the monthly totals tie to the billing summary.
Step 3: Export the chart, report, or deck
Take out the monthly trend, a movement table by component, or a board-ready slide with the figures and the definitions on it.
Why this beats rebuilding it monthly
| Manual route | Powerdrill Bloom | |
|---|---|---|
| Normalising annual plans | Formula column per file | Upload and state the rule |
| Movement breakdown | Prior-month snapshot to maintain | Ask for the components |
| Excluding trials and metered lines | Manual filters each cycle | State the exclusions |
| Reconciling to the billing summary | Manual check | Ask whether the totals tie |
The middle rows are where the days go. Summing a column is not the work; keeping five definitions stable across months is.
Common mistakes
Summing invoices instead of subscriptions. Invoices include one-off charges and prorations. Recurring revenue is a property of the subscription, not the bill.
Leaving tax in the amount. Tax inflates every month and never nets out. Strip it before normalising.
Counting trials as revenue. A trial has no recurring amount yet. Including it borrows next month's growth.
Treating ARR as MRR times twelve without saying so. It is a normalised annual figure, not cash collected. Label it so nobody reads it as bookings.
Ignoring the coupon-to-churn effect. A full discount drops a subscriber to zero, which reads as churn. Flag those rows rather than explaining them later.
Dividing churn by the opening count. The documented denominator includes the subscribers added during the window. The two versions produce different rates on identical data.
Rebuilding from scratch each month. The definitions do not change; only the export does. Keep the rules and swap the file, the same discipline as a budget versus actual report.
Conclusion
Fix the status list, decide on discounts, normalise the interval, and report as of a month end. Those four make an MRR report that survives a question from finance.
The expensive part is not the sum. It is that five definitions have to hold steady every month while the export changes shape.
If that is where your month end goes, try Powerdrill Bloom on your subscription export. See also our guide to setting KPI targets from your own data. The roundup of AI tools for SaaS metrics tracking and the AI financial analysis page cover the tooling side.
Frequently asked questions
What is the formula for MRR from a subscription export?
Normalise every subscription to a monthly amount, then sum the ones with a qualifying status. Stripe's example is (100 × $100) + (50 × ($600 / 12)) = $12,500.
How do I convert MRR to ARR?
Multiply the monthly figure by twelve. Label it as a normalised annual run rate rather than cash collected, because annual plans are billed up front.
Should usage-based revenue be included?
Stripe excludes metered products from MRR. If a meaningful share of your revenue is usage-based, report it as a separate line rather than folding it in.
Which subscription statuses count as active?
The documented default is active plus past_due. Canceled and unpaid subscriptions are treated as churn and drop out of the total.
Why does my churn rate differ from the billing dashboard?
Most often it is the denominator. The documented calculation divides by the subscribers active thirty days ago plus the new subscribers added during the window.