·10 min read

How to Calculate MRR in Stripe (Step-by-Step)

Monthly Recurring Revenue (MRR) is the most important metric for any SaaS business. It’s also one of the trickiest to calculate accurately from raw Stripe data. Stripe doesn’t give you a single “MRR” field — you have to derive it from subscriptions, prices, invoices, and a handful of edge cases that can throw your numbers off.

This guide walks you through exactly how to calculate MRR from your Stripe account, step by step. If you’re not sure what MRR is or why it matters, start with our complete guide to MRR before diving into the technical implementation.

Step 1: Understand the Stripe Data Model

Before writing any code, you need to understand which Stripe objects contain the data you need. The key objects for MRR calculation are:

  • Subscriptions — the core object. Each subscription has a status, one or more items, and billing interval information. The Subscription API is your starting point.
  • Subscription Items — each item references a Price and a quantity. A single subscription can have multiple items (e.g., a base plan plus add-ons).
  • Prices — define the amount, currency, and billing interval. A Price can be recurring (monthly, yearly, etc.) or one-time. Only recurring prices contribute to MRR. See the Prices API documentation.
  • Coupons and Discounts — applied at the subscription or customer level. These reduce the effective amount billed and must be factored into your MRR calculation.

Step 2: Fetch Active Subscriptions

MRR only includes revenue from active subscriptions. In Stripe, you want subscriptions with status equal to active or trialing (more on trials later). Filter out canceled, incomplete, incomplete_expired, past_due, and unpaid subscriptions.

Here’s a basic approach using the Stripe API:

// Fetch all active subscriptions (paginated)
const subscriptions = [];
let hasMore = true;
let startingAfter = undefined;

while (hasMore) {
  const response = await stripe.subscriptions.list({
    status: 'active',
    limit: 100,
    ...(startingAfter && { starting_after: startingAfter }),
  });
  subscriptions.push(...response.data);
  hasMore = response.has_more;
  startingAfter = response.data[response.data.length - 1]?.id;
}

For a complete overview of how Stripe structures subscriptions, refer to the Stripe subscriptions overview.

Try StripeReport Free

Get the Stripe revenue reports you’ve been missing

MRR tracking, cash flow forecasts, churn analytics, and daily email reports — all from your Stripe data. 3-day free trial.

Start Your Free Trial →

Step 3: Normalize Billing Intervals to Monthly

The core challenge in MRR calculation is that not all subscriptions bill monthly. Annual plans, quarterly plans, and even weekly plans all need to be normalized to a monthly equivalent.

For each subscription item, calculate the monthly contribution:

function normalizeToMonthly(amount, interval, intervalCount) {
  switch (interval) {
    case 'day':
      return (amount / intervalCount) * 30;
    case 'week':
      return (amount / intervalCount) * (30 / 7);
    case 'month':
      return amount / intervalCount;
    case 'year':
      return amount / (intervalCount * 12);
    default:
      return 0;
  }
}

The interval and interval_count fields come from the Price object. A yearly price has interval: "year" and interval_count: 1. A price billed every 6 months would have interval: "month" and interval_count: 6.

Step 4: Handle Quantities

Each subscription item has a quantity field. For seat-based pricing, this represents the number of seats. Multiply the normalized price by the quantity:

const itemMRR = normalizeToMonthly(
  price.unit_amount,
  price.recurring.interval,
  price.recurring.interval_count
) * item.quantity;

Step 5: Apply Discounts

Discounts are one of the most commonly missed factors in MRR calculation. A subscription with a 20% coupon should contribute 20% less MRR, not the full list price.

Stripe coupons can be percentage-based or fixed-amount. They can also be applied at the subscription level or the customer level. Check both:

function applyDiscount(amount, discount) {
  if (!discount || !discount.coupon) return amount;
  const coupon = discount.coupon;
  if (coupon.percent_off) {
    return amount * (1 - coupon.percent_off / 100);
  }
  if (coupon.amount_off) {
    return Math.max(0, amount - coupon.amount_off);
  }
  return amount;
}

MRR Growth

$18k
Jan
$22k
Feb
$25k
Mar
$31k
Apr
$36k
May
$42k
Jun
MRR trending upward over six months — the growth pattern every SaaS founder wants to see

Step 6: Handle Trials

Trialing subscriptions are a judgment call. There are two schools of thought:

  • Exclude trials from MRR. The customer hasn’t paid yet, so counting them as revenue is premature. This is the more conservative (and generally recommended) approach.
  • Include trials as “pipeline MRR.” Some companies track trials separately as a leading indicator of future MRR, but don’t mix them into the primary MRR number.

In Stripe, trialing subscriptions have status: "trialing" and a trial_end timestamp. If you exclude trials, simply skip these subscriptions. If you track them separately, calculate their potential MRR the same way but report it in a different bucket.

Our Stripe subscription billing guide covers trial configuration in detail.

Step 7: Handle Paused Subscriptions

Stripe supports pausing subscriptions via pause_collection. A paused subscription is technically still activebut isn’t collecting payments. These should be excluded from MRR.

// Skip paused subscriptions
if (subscription.pause_collection) {
  continue;
}

Step 8: Put It All Together

Here’s the complete MRR calculation logic:

let totalMRR = 0;

for (const sub of subscriptions) {
  if (sub.pause_collection) continue;

  let subMRR = 0;
  for (const item of sub.items.data) {
    const price = item.price;
    if (price.type !== 'recurring') continue;

    let itemMRR = normalizeToMonthly(
      price.unit_amount,
      price.recurring.interval,
      price.recurring.interval_count
    ) * item.quantity;

    // Apply subscription-level discount
    if (sub.discount) {
      itemMRR = applyDiscount(itemMRR, sub.discount);
    }

    subMRR += itemMRR;
  }
  totalMRR += subMRR;
}

// Convert from cents to dollars
totalMRR = totalMRR / 100;

Try StripeReport Free

Get the Stripe revenue reports you’ve been missing

MRR tracking, cash flow forecasts, churn analytics, and daily email reports — all from your Stripe data. 3-day free trial.

Start Your Free Trial →

Common Pitfalls

Even with the right logic, there are several traps that produce inaccurate MRR numbers:

  • Multi-currency subscriptions. If you bill in multiple currencies, you need to convert everything to a base currency using consistent exchange rates. Don’t mix USD and EUR amounts.
  • Metered billing. Usage-based prices (recurring.usage_type: "metered") don’t have a fixed amount. You’ll need to estimate MRR from historical usage or exclude metered components.
  • Tax-inclusive pricing. If your prices include tax, decide whether your MRR should be gross (including tax) or net (excluding tax). Most SaaS companies report MRR net of tax.
  • Schedule-based changes. Stripe Subscription Schedules allow future plan changes. Your current MRR should reflect current pricing, not scheduled future changes.

For ARPU calculations that build on MRR, see our Stripe ARPU calculation guide.

The Easier Way: Use a Dashboard

Building MRR calculation from scratch is a useful exercise for understanding your data, but maintaining it over time is a burden. Edge cases multiply as your billing grows more complex, and small bugs can silently distort your metrics for weeks before anyone notices.

StripeReport’s MRR dashboardconnects directly to your Stripe account and handles all of the normalization, discount application, trial exclusion, and currency conversion automatically. It also breaks down MRR into its components — new, expansion, contraction, churn, and reactivation — so you can see exactly what’s driving changes month over month.

Key Takeaways

  • MRR calculation requires fetching active subscriptions, normalizing billing intervals, applying discounts, and handling edge cases like trials and paused subscriptions.
  • The core Stripe objects you need are Subscriptions, Subscription Items, and Prices.
  • Always normalize annual and other non-monthly plans to their monthly equivalent.
  • Exclude paused subscriptions and decide on a consistent policy for trials.
  • Watch for pitfalls: multi-currency, metered billing, and tax-inclusive pricing.