6 min read

How to Monitor ARPU in Stripe

ARPU is one of the most telling metrics for a subscription business. In Stripe, you calculate it by dividing your total revenue by your customer count. The challenge isn't the math—it's reliably pulling the right numbers from Stripe's API and keeping them fresh.

Calculate ARPU from Stripe's API

Start by fetching your invoices and customer counts directly from Stripe.

Fetch all paid invoices for a time period

Use the invoices endpoint to get all invoices in a date range. Filter by status: paid to only count revenue that's actually landed. Use created to limit to a specific month or year.

javascript
const stripe = require('stripe')(process.env.STRIPE_SECRET_KEY);

const invoices = await stripe.invoices.list({
  status: 'paid',
  created: {
    gte: Math.floor(new Date('2025-01-01').getTime() / 1000),
    lte: Math.floor(new Date('2025-12-31').getTime() / 1000)
  },
  limit: 100
});

const totalRevenue = invoices.data.reduce((sum, inv) => sum + inv.total, 0) / 100;
console.log(`Total revenue: $${totalRevenue}`);

// Handle pagination
let allInvoices = invoices.data;
let hasMore = invoices.has_more;
let lastId = invoices.data[invoices.data.length - 1]?.id;

while (hasMore) {
  const page = await stripe.invoices.list({
    status: 'paid',
    created: { gte: Math.floor(new Date('2025-01-01').getTime() / 1000) },
    starting_after: lastId,
    limit: 100
  });
  allInvoices = allInvoices.concat(page.data);
  hasMore = page.has_more;
  lastId = page.data[page.data.length - 1]?.id;
}
Fetch all paid invoices and sum their totals

Count active customers in the same period

Get your customer count for the same timeframe using the customers endpoint or the Customers section in the Stripe Dashboard. For ARPU, count only customers with activity (invoices) in your period.

javascript
const customers = await stripe.customers.list({
  created: {
    gte: Math.floor(new Date('2025-01-01').getTime() / 1000),
    lte: Math.floor(new Date('2025-12-31').getTime() / 1000)
  },
  limit: 100
});

let allCustomers = customers.data;
let hasMore = customers.has_more;
let lastId = customers.data[customers.data.length - 1]?.id;

while (hasMore) {
  const page = await stripe.customers.list({
    created: { gte: Math.floor(new Date('2025-01-01').getTime() / 1000) },
    starting_after: lastId,
    limit: 100
  });
  allCustomers = allCustomers.concat(page.data);
  hasMore = page.has_more;
  lastId = page.data[page.data.length - 1]?.id;
}

const customerCount = allCustomers.length;
console.log(`Active customers: ${customerCount}`);

const arpu = totalRevenue / customerCount;
console.log(`ARPU: $${arpu.toFixed(2)}`);
Watch out: Newly created customers with no invoices inflate your denominator. Filter to customers with at least one paid invoice to get an accurate number.

Track ARPU trends with Stripe Sigma

For continuous monitoring, use Stripe Sigma—your Stripe account's SQL engine. Query your data directly without pagination loops.

Access Stripe Sigma from the Dashboard

Navigate to Developers > Sigma in your Stripe Dashboard. Create a new query to write SQL against your live Stripe data.

Write a SQL query to calculate ARPU

In Sigma, query the invoices and customers tables directly. Sum revenue, count unique customers, and divide to get ARPU by time period.

javascript
-- Stripe Sigma SQL: Monthly ARPU
SELECT
  DATE_TRUNC('month', invoices.created) AS month,
  SUM(invoices.total) / 100 AS total_revenue,
  COUNT(DISTINCT invoices.customer) AS customer_count,
  ROUND(SUM(invoices.total) / 100.0 / COUNT(DISTINCT invoices.customer), 2) AS arpu
FROM invoices
WHERE invoices.status = 'paid'
  AND invoices.created >= DATE '2025-01-01'
GROUP BY DATE_TRUNC('month', invoices.created)
ORDER BY month DESC;
Calculate ARPU by month using Stripe Sigma SQL
Tip: Sigma queries run against live data but don't auto-refresh. Bookmark your query and run it weekly or monthly to watch trends.

Automate ARPU tracking with webhooks

For real-time updates, listen to Stripe webhook events and recalculate ARPU whenever revenue changes.

Listen for invoice payment events

Set up a webhook endpoint to listen for invoice.payment_succeeded and invoice.payment_failed events. Each time an invoice is paid, Stripe pings your endpoint.

javascript
const express = require('express');
const stripe = require('stripe')(process.env.STRIPE_SECRET_KEY);
const endpointSecret = process.env.STRIPE_WEBHOOK_SECRET;

const app = express();
app.post('/webhook', express.raw({ type: 'application/json' }), (req, res) => {
  const sig = req.headers['stripe-signature'];
  let event;

  try {
    event = stripe.webhooks.constructEvent(req.body, sig, endpointSecret);
  } catch (err) {
    return res.status(400).send(`Webhook Error: ${err.message}`);
  }

  if (event.type === 'invoice.payment_succeeded') {
    const invoice = event.data.object;
    console.log(`Invoice ${invoice.id} paid: $${invoice.total / 100}`);
    recalculateARPU();
  }

  res.json({ received: true });
});

function recalculateARPU() {
  // Fetch latest invoices and customers, compute new ARPU
  // Store result in database or cache
}

app.listen(3000, () => console.log('Webhook server running'));

Store ARPU in a database or cache

After each webhook, save your calculated ARPU to a database or Redis cache. This avoids recalculating from scratch and lets you build a historical trend.

Common Pitfalls

  • Counting trial customers with no revenue inflates your denominator—filter to customers with at least one paid invoice.
  • Using amount_paid instead of total double-counts if a customer has partial payments.
  • Not paginating API responses means you'll miss invoices and customers beyond the first 100 results.
  • Forgetting to convert from cents—all amounts in Stripe's API are in the smallest currency unit (cents for USD).

Wrapping Up

With the API, Sigma, or webhooks, you now have a clear view of revenue per customer. ARPU trends reveal churn, upsell wins, and pricing changes faster than any other metric. If you want to track this automatically across tools and correlate it with behavioral data, Product Analyst can help.

Track these metrics automatically

Product Analyst connects to your stack and surfaces the insights that matter.

Try Product Analyst — Free