Metric · Revenue

What is net revenue retention, and how do you measure it in Metabase?

Net revenue retention (NRR) measures how much recurring revenue you keep from an existing cohort of customers over time, including expansion and after churn and downgrades. Above 100% means your existing base grows even without new customers — the hallmark of a durable subscription business. Measure it in Metabase from billing data synced into a database (Stripe, Chargebee, Paddle, or Recurly).

TL;DR — NRR = (starting MRR + expansion − contraction − churn) ÷ starting MRR, for a fixed cohort, excluding new customers. Over 100% = net expansion. Report it next to churn.

How is NRR calculated?

Take a cohort of customers as of a start date, then compare their MRR one period later (typically 12 months):

NRR = (starting MRR + expansion − contraction − churned) ÷ starting MRR

  • Only count customers who existed at the start — exclude new logos.
  • Expansion (upgrades, add-ons, seats) pushes NRR up.
  • Contraction and churn pull it down.

NRR vs. gross revenue retention (GRR)

  • GRR counts only losses (churn + contraction) and caps each customer at their starting MRR — it can never exceed 100%. It shows how well you hold the floor.
  • NRR also credits expansion, so it can exceed 100%. It shows whether the base compounds.

Report both: strong NRR with weak GRR means expansion is masking real churn.

What data does NRR need?

  • A monthly MRR model at the customer grain.
  • A stable customer identifier to follow a cohort across months.
  • Expansion/contraction captured as MRR changes, not just plan swaps.

SQL patterns

NRR and GRR for a 12-month cohortPostgreSQL

Follows the customers active 12 months ago and compares their MRR today.

-- Requires a monthly MRR model with one row per customer per month
WITH cohort AS (          -- customers active 12 months ago
  SELECT customer_id, SUM(mrr) AS start_mrr
  FROM modeled_mrr
  WHERE month = date_trunc('month', CURRENT_DATE - INTERVAL '12 months')
  GROUP BY customer_id
),
now AS (                  -- the same customers' MRR today
  SELECT customer_id, SUM(mrr) AS end_mrr
  FROM modeled_mrr
  WHERE month = date_trunc('month', CURRENT_DATE)
  GROUP BY customer_id
)
SELECT
  ROUND(100.0 * SUM(COALESCE(n.end_mrr, 0)) / NULLIF(SUM(c.start_mrr), 0), 1)
    AS nrr_pct,
  ROUND(100.0 * SUM(LEAST(COALESCE(n.end_mrr, 0), c.start_mrr))
    / NULLIF(SUM(c.start_mrr), 0), 1) AS grr_pct
FROM cohort c
LEFT JOIN now n ON n.customer_id = c.customer_id;

Pitfalls

Including new customers.→ NRR is about the existing base — new logos belong in growth, not retention.
Confusing NRR with GRR.→ GRR ignores expansion and caps at 100%; NRR credits expansion. Label which one you show.
Inconsistent cohort windows.→ Fix the start month and horizon (e.g. trailing 12 months) and apply it the same way every time.
Letting a few big accounts dominate silently.→ Segment NRR by plan or size so one whale doesn't hide broad churn.

Where this metric applies

Each needs a customer-grain monthly MRR model built from synced subscription data.

Analytics

Metrics

FAQ

What's a good NRR?
For B2B SaaS, 100% means the existing base is flat; best-in-class often sits well above 110%. SMB and consumer businesses tend to run lower. Track your trend rather than a single benchmark.
Is NRR measured on customers or revenue?
Revenue. NRR follows the MRR of a fixed cohort of customers, so it captures expansion and contraction, not just how many logos stayed.
Do I need customer-level MRR?
Yes. NRR follows a cohort of customers over time, so your monthly MRR model should be resolvable to a stable customer id.