EnableYourData.com

KPI · Subscriptions and SaaS

Gross revenue retention (GRR): formula and example.

Gross revenue retention (GRR) is the MRR from existing customers after a period, excluding expansion, divided by their MRR at the start, as a percentage. Only contraction and cancellations count; upgrades and extra seats are left out. GRR shows how well you hold on to the revenue you already have, which is why it can never exceed 100%.

Gross revenue retention (GRR) formula

(Starting MRR − contraction − churn) ÷ starting MRR × 100%

Worked example

Customers active with Acme's subscription service on 1 October 2025 were worth €36,000 MRR. A year later, €1,080 has been lost to contraction and €2,520 to cancellations. GRR is (€36,000 − €1,080 − €2,520) ÷ €36,000 × 100% = €32,400 ÷ €36,000 × 100% = 90%.

Fictitious figures for Acme Groothandel, a sample wholesaler.

How to read this KPI

Higher GRR means you lose less existing revenue; it is a clean retention measure because expansion cannot hide the losses. Compare GRR with NRR: a large gap means growth relies heavily on expansion within some accounts. Track GRR by segment and plan, and when it falls, look at the reasons for cancellations and downgrades.

Pitfalls with gross revenue retention (GRR)

  • Not capping expansion per customer, so one customer's upgrade offsets another customer's loss.
  • Including customers who started during the period in the starting MRR.
  • Treating a temporary pause as a cancellation, or a permanent cancellation as a pause.

SQL & DAX

Calculating gross revenue retention (GRR) in SQL and DAX

Two examples on a fictitious data warehouse for Acme Groothandel: a PostgreSQL query and a measure for a Power BI model. Adjust table and column names to your own model.

SQL · PostgreSQL
WITH per_customer AS (
  SELECT customer_id,
         SUM(mrr) FILTER (WHERE started_at <= current_date - interval '1 year'
           AND (ended_at IS NULL OR ended_at > current_date - interval '1 year')) AS start_mrr,
         SUM(mrr) FILTER (WHERE started_at <= current_date
           AND (ended_at IS NULL OR ended_at > current_date)) AS end_mrr
  FROM subscriptions
  GROUP BY customer_id
)
SELECT SUM(start_mrr) AS start_mrr,
       SUM(LEAST(COALESCE(end_mrr, 0), start_mrr)) AS retained_mrr,
       ROUND(100.0 * SUM(LEAST(COALESCE(end_mrr, 0), start_mrr)) / NULLIF(SUM(start_mrr), 0), 1) AS grr_pct
FROM per_customer
WHERE start_mrr > 0;
DAX · Power BI
GRR (12 months) % =
VAR StartDate = EDATE(MAX('Date'[Date]), -12)
VAR Window = DATESINPERIOD('Date'[Date], MAX('Date'[Date]), -12, MONTH)
VAR Cohort =
    CALCULATETABLE(VALUES(MrrMovements[customer_id]), REMOVEFILTERS('Date'), MrrMovements[month] <= StartDate)
VAR StartMRR = CALCULATE([MRR], DATEADD('Date'[Date], -12, MONTH))
VAR Lost =
    CALCULATE(SUM(MrrMovements[amount]), Window, Cohort, MrrMovements[movement_type] IN {"contraction", "churn"})
RETURN
    DIVIDE(StartMRR - Lost, StartMRR)

In ENABLE

Tracking this KPI in ENABLE

Plain-language questions

Ask for gross revenue retention (GRR) per month, customer or product in the SQL Explorer with AI. The AI writes the SQL, you see the query and run it yourself; the AI only receives metadata.

Read more →

In your Power BI dashboard

Define the KPI as a measure in your Power BI model and show it in the portal, with "Last refreshed" next to it. Access profiles and optional row-level security decide who sees which figures.

Read more →

Custom dashboards (pilot)

Add the KPI as a tile to a custom dashboard, compared with last year. The Dashboard Builder is a pilot and can be switched on per client.

Read more →

Monthly targets

With the built-in Targets app you set a target for the KPI per month, so you see actuals and target side by side.

Read more →

FAQ

Frequently asked questions

How do you calculate gross revenue retention?

Take the MRR of customers active at the start of the period, subtract contraction and cancellations, and divide the result by the starting MRR. Expansion is not included. With €80,000 starting MRR and €6,400 lost, GRR is 92%.

Why can GRR not exceed 100%?

Because expansion from existing customers is excluded, the group's MRR can only stay the same or fall. Each customer counts for at most their original MRR. GRR of 100% means you have not lost a single euro of existing revenue.

What does the gap between GRR and NRR tell you?

The gap between NRR and GRR is the contribution of expansion within existing accounts. NRR of 108% with GRR of 90% means expansion adds 18 percentage points. The bigger the gap, the more growth depends on upselling to some of your customers.

Use AI on your own data. Securely, and without the headache.

In an online demo we show how ENABLE makes your data securely available and how you build on it: describing an app in the AI Builder, plain-language questions, dashboards and APIs. And how we set it up and manage it for you.