ARPU (Average Revenue Per User) is total revenue divided by number of customers—and it's the metric that separates healthy SaaS businesses from those in trouble. In Stripe, ARPU matters because it tells you whether your pricing, upsells, and retention strategies are actually working. If ARPU is flat while you're adding customers, you have a real problem.
Calculate ARPU From Stripe Invoices
ARPU is straightforward to compute using the Stripe API, but you need to query the right data.
Fetch Customers and Paid Invoices
Use stripe.customers.list() to get your customer count, and stripe.invoices.list() filtered by status: 'paid' to sum actual revenue. The Stripe Dashboard shows a revenue overview under Metrics, but to calculate exact ARPU you need the API. Always use paid invoices, not charged amounts, to avoid double-counting refunds.
const stripe = require('stripe')(process.env.STRIPE_SECRET_KEY);
// Get all active customers
const customers = await stripe.customers.list({ limit: 100 });
// Sum revenue from paid invoices only
const invoices = await stripe.invoices.list({
status: 'paid',
limit: 100,
});
const totalRevenue = invoices.data.reduce((sum, inv) => {
return sum + inv.amount_paid;
}, 0);
const arpu = totalRevenue / customers.data.length / 100; // divide by 100 for cents-to-dollars
console.log(`ARPU: $${arpu.toFixed(2)}`);
Calculate Monthly ARPU to Track Trends
ARPU changes month to month. Filter invoices by creation date using created with gte and lt operators. Count unique customers in that period by extracting the customer ID from each invoice. Compare month-over-month to spot whether your business is growing or stalling.
const stripe = require('stripe')(process.env.STRIPE_SECRET_KEY);
const startOfMonth = Math.floor(new Date(2025, 0, 1).getTime() / 1000);
const endOfMonth = Math.floor(new Date(2025, 1, 1).getTime() / 1000);
const invoices = await stripe.invoices.list({
status: 'paid',
created: {
gte: startOfMonth,
lt: endOfMonth,
},
limit: 100,
});
const monthlyRevenue = invoices.data.reduce((sum, inv) => sum + inv.amount_paid, 0);
const uniqueCustomers = new Set(invoices.data.map(inv => inv.customer)).size;
const monthlyArpu = monthlyRevenue / uniqueCustomers / 100;
console.log(`Monthly ARPU: $${monthlyArpu.toFixed(2)}`);
Use ARPU to Spot Churn and Validate Pricing
Raw ARPU is useful, but segmented ARPU—by cohort, pricing plan, or customer source—reveals what's actually driving growth.
Tag Customers by Pricing Cohort
When you change pricing, tag customers with metadata using stripe.customers.update(). Add fields like pricing_cohort and pricing_date to identify which version they're on. Later, slice your ARPU calculation by cohort to measure whether the new price actually worked.
const stripe = require('stripe')(process.env.STRIPE_SECRET_KEY);
// Tag a customer with cohort metadata
await stripe.customers.update(customerId, {
metadata: {
pricing_cohort: 'v2_increase',
pricing_date: '2025-01-15',
},
});
// Later: Calculate ARPU only for new pricing cohort
const allCustomers = await stripe.customers.list({ limit: 100 });
const newCohort = allCustomers.data.filter(
c => c.metadata?.pricing_cohort === 'v2_increase'
);
console.log(`Customers in new pricing: ${newCohort.length}`);
Monitor Invoice Count Per Customer as a Churn Signal
Declining ARPU often means churn before cancellation rates show it. If average invoice count per customer drops, customers are either downgrading or using less. Query the last 12 months of invoices per customer and calculate the average invoice amount. Low average = customer at risk.
const stripe = require('stripe')(process.env.STRIPE_SECRET_KEY);
const customers = await stripe.customers.list({ limit: 100 });
for (const customer of customers.data) {
const invoices = await stripe.invoices.list({
customer: customer.id,
limit: 12,
});
const avgInvoiceAmount = invoices.data.length > 0
? invoices.data.reduce((sum, inv) => sum + inv.amount_paid, 0) / invoices.data.length / 100
: 0;
if (avgInvoiceAmount < 50) { // Below $50/month
console.log(`At-risk customer: ${customer.id} ($${avgInvoiceAmount.toFixed(2)}/month)`);
}
}
Common Pitfalls
- Counting all customers ever created inflates your denominator and kills ARPU. Include only customers with invoices in your analysis period.
- Using charged amounts instead of paid invoice amounts double-counts refunds and failed payments. Always filter by
status: 'paid'. - Forgetting to exclude test mode data. Query with
livemode: trueto avoid mixing test charges into your real metrics. - Not converting currencies. If you operate globally, convert all invoice amounts to a single base currency before summing.
Wrapping Up
ARPU is your pulse check for business health in Stripe. Calculate it monthly, segment by cohort, and use it to validate pricing changes and detect churn early. Healthy SaaS businesses see 3–5% quarter-over-quarter ARPU growth. If you want to track this automatically across tools, Product Analyst can help.