Knowing your MRR is critical — it tells you the predictable revenue flowing in each month. But Stripe doesn't calculate it for you automatically. You need to query your subscriptions, sum their recurring amounts, and handle the fact that subscriptions might bill yearly or quarterly.
Query Active Subscriptions
Start by fetching all subscriptions with status 'active' from Stripe.
List all active subscriptions
Use the Subscriptions API to fetch subscriptions where status: 'active'. This pulls every subscription currently billing your customers. The response includes the subscription's items (products and prices) and billing details.
const stripe = require('stripe')(process.env.STRIPE_SECRET_KEY);
const subscriptions = await stripe.subscriptions.list({
status: 'active',
limit: 100
});Handle pagination if needed
If you have more than 100 subscriptions, use the starting_after parameter to paginate through results. Store the id of the last subscription from the previous request and pass it in the next call.
let allSubscriptions = [];
let hasMore = true;
let startingAfter = null;
while (hasMore) {
const batch = await stripe.subscriptions.list({
status: 'active',
limit: 100,
starting_after: startingAfter
});
allSubscriptions = allSubscriptions.concat(batch.data);
hasMore = batch.has_more;
if (batch.data.length > 0) {
startingAfter = batch.data[batch.data.length - 1].id;
}
}status: 'past_due' won't be included — those have failed payments. Add a separate query if you want to include them.Sum Recurring Amounts
Once you have the subscriptions, iterate through each one and add up the monthly revenue.
Extract monthly recurring amounts
For each subscription, loop through its items array. Each item has a price object with unit_amount (in cents) and recurring details. Extract only items with recurring.interval === 'month'. Multiply unit_amount by quantity to account for customers buying multiple licenses.
let mrr = 0;
subscriptions.data.forEach(subscription => {
subscription.items.data.forEach(item => {
const price = item.price;
if (price.recurring && price.recurring.interval === 'month') {
mrr += price.unit_amount * item.quantity;
}
});
});
// Convert from cents to dollars
mrr = mrr / 100;Annualize non-monthly subscriptions
Subscriptions billed yearly or quarterly need to be converted to a monthly equivalent. Divide yearly amounts by 12, quarterly by 3. This normalizes everything to monthly revenue. Add the result to your MRR.
let mrr = 0;
subscriptions.data.forEach(subscription => {
subscription.items.data.forEach(item => {
const price = item.price;
if (price.recurring) {
const interval = price.recurring.interval;
const amount = price.unit_amount * item.quantity;
if (interval === 'month') {
mrr += amount;
} else if (interval === 'year') {
mrr += amount / 12;
} else if (interval === 'quarter') {
mrr += amount / 3;
}
}
});
});
mrr = mrr / 100;interval_count. A subscription with interval: 'year' and interval_count: 2 bills every 2 years, not every year — divide by 24 instead of 12.Handle Edge Cases
Real MRR calculations need to account for trial periods and get precise when deals are involved.
Exclude trial subscriptions
Subscriptions in trial phase don't generate revenue yet. Check the trial_end timestamp. If it's in the future (trial is active), exclude this subscription from your MRR — the customer isn't being charged.
const now = Math.floor(Date.now() / 1000); // Unix timestamp in seconds
subscriptions.data.forEach(subscription => {
// Skip if currently in trial
if (subscription.trial_end && subscription.trial_end > now) {
return; // Don't count this subscription
}
// ... calculate MRR for this subscription
});Account for discounts and prorations
The Subscriptions API doesn't expose prorated amounts or discounts directly. For precise MRR including prorations, query the Invoices API and sum the amount_due for open invoices with a subscription field. This is slower but captures the actual revenue Stripe will collect.
// More accurate: sum current invoices
const invoices = await stripe.invoices.list({
status: 'open',
limit: 100
});
let accurateMrr = 0;
invoices.data.forEach(invoice => {
// Only count invoices tied to subscriptions
if (invoice.subscription) {
accurateMrr += invoice.amount_due;
}
});
accurateMrr = accurateMrr / 100;Common Pitfalls
- Forgetting to divide by 100 — Stripe stores amounts in cents, not dollars.
- Not annualizing yearly/quarterly subscriptions — they'll distort your MRR calculation.
- Including trial subscriptions — customers in trial aren't being charged yet.
- Ignoring multiple currencies — if you have USD and EUR subscriptions, sum them separately or convert first.
Wrapping Up
You now have a complete MRR calculation from Stripe: query active subscriptions, sum their recurring amounts, handle different billing intervals, and account for trials. This gives you the predictable revenue entering your business each month. If you want to track this automatically across all your tools and keep it updated in real-time, Product Analyst can help.