Chart your export here
Drop a CSV here. xmetric reads every row in this browser and draws a first chart you can regroup or change the measure of. Nothing is uploaded.
No file loaded yet. You can also drop a CSV on this box.
How to export your invoice history from Stripe for NRR
To calculate trailing 12-month (T12M) NRR, your CSV export must span at least 13 completed months.
- Open the Stripe Dashboard and go to Billing > Invoices.
- Click Export, set a custom date range covering at least 13 to 24 months, and select All columns.
- Download
invoices.csv. Drop it above for a first chart, or import it into the xmetric app to build the NRR view.
Stripe CSV columns used for NRR and GRR
customer(orCustomer ID): unique Stripe customer ID (cus_...), used to track expansion and contraction across subscriptions.subscription: filters out one-time non-recurring invoices (subscriptionmust not be empty).status: filtered topaid.created (UTC)(orCreated date (UTC)/period_start (UTC)): maps revenue to the billing month.amount_paid: amount collected on the invoice.
Tableau LOD and Table Calculation formulas for NRR vs. GRR
- Net Revenue Retention (NRR):
(Starting MRR + Expansion - Contraction - Churn) / Starting MRRfor the cohort of customers who were active in the starting period. Can exceed100%. - Gross Revenue Retention (GRR):
(Starting MRR - Contraction - Churn) / Starting MRR, capping each customer's ending MRR at their starting MRR so expansion is excluded. Cannot exceed100%.
1. Customer MRR by Month (FIXED LOD)
// [Customer Monthly MRR]
{ FIXED [customer], DATETRUNC('month', [created (UTC)]) :
SUM(IF [status] = "paid" AND NOT ISNULL([subscription]) THEN [Normalized MRR] ELSE 0 END)
}Test this LOD in the formula playground, then build the monthly view on shelves in the xmetric app.
2. Trailing 12-Month NRR and GRR (SQL equivalent)
The equivalent SQL for the customer-level lookback:
WITH monthly_customer_mrr AS (
SELECT
customer AS customer_id,
DATE_TRUNC('month', CAST("created (UTC)" AS TIMESTAMP)) AS bill_month,
SUM(
CASE
WHEN interval = 'year' THEN amount_paid / 12.0
ELSE amount_paid
END
) AS mrr
FROM stripe_invoices
WHERE status = 'paid'
AND subscription IS NOT NULL
AND subscription <> ''
AND amount_paid > 0
GROUP BY 1, 2
),
paired_12m AS (
SELECT
start_m.bill_month + INTERVAL '12 months' AS report_month,
start_m.customer_id,
start_m.mrr AS starting_mrr,
COALESCE(end_m.mrr, 0) AS ending_mrr,
LEAST(start_m.mrr, COALESCE(end_m.mrr, 0)) AS retained_gross_mrr
FROM monthly_customer_mrr start_m
LEFT JOIN monthly_customer_mrr end_m
ON start_m.customer_id = end_m.customer_id
AND end_m.bill_month = start_m.bill_month + INTERVAL '12 months'
)
SELECT
report_month,
COUNT(DISTINCT customer_id) AS base_cohort_customers,
ROUND(SUM(starting_mrr), 2) AS starting_mrr_12m_ago,
ROUND(SUM(ending_mrr), 2) AS ending_mrr_today,
ROUND(100.0 * SUM(ending_mrr) / NULLIF(SUM(starting_mrr), 0), 1) AS annual_nrr_pct,
ROUND(100.0 * SUM(retained_gross_mrr) / NULLIF(SUM(starting_mrr), 0), 1) AS annual_grr_pct
FROM paired_12m
WHERE report_month <= (SELECT MAX(bill_month) FROM monthly_customer_mrr)
GROUP BY 1
ORDER BY 1;Common NRR calculation errors on Stripe exports
- Including new customers acquired during the window: NRR strictly measures the cohort of customers who existed at the start of the period (
start_m.mrr > 0). If a new customer signs up in Month 6, their revenue is excluded from the denominator and numerator until they have 12 months of history. - Letting one customer's expansion hide another customer's churn in GRR: In Gross Revenue Retention (GRR), you must apply
LEAST(starting_mrr, ending_mrr)at the individual customer level before summing across the cohort. TakingLEASTat the aggregate level produces a wrong number. - Duplicate Customer IDs when a company changes billing email: If an existing customer creates a second Stripe
cus_...record when upgrading to an annual contract, Stripe treats them as one churned customer and one new customer. If you sell B2B, create a calculated field in the xmetric app that groups by email domain (SPLIT([Customer Email], '@', 2)) to merge duplicate Stripe customer records.
Run NRR audits from Claude or ChatGPT
Every calculation in xmetric is a deterministic command. An MCP server for Claude and ChatGPT is in development, so you will be able to ask your AI assistant for NRR and GRR numbers from a Stripe CSV without relying on LLM arithmetic. Live connections to Postgres and BigQuery are also coming.
Questions people ask
Should early-stage SaaS track monthly NRR or annual (12-month) NRR?
If you have fewer than 12 months of billing history, use a 1-month lookback (INTERVAL '1 month') instead of a 12-month lookback. Keep in mind that a 99% monthly NRR compounds to 0.99^12 = 88.6% annual NRR.
Can GRR ever be higher than 100%?
No. Because GRR caps every customer's ending MRR at their starting MRR (MIN([Starting MRR], [Ending MRR])), GRR is bounded between 0% and 100%. Any number above 100% means expansion revenue leaked into the calculation.
Does xmetric upload my Stripe invoice CSV?
No. Your CSV is read inside your browser tab. It leaves the browser only if you sign in and save a workbook online.
Drop your invoices.csv above for a first chart, then build your NRR and GRR curves in the xmetric app.