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.
KPI · Subscriptions and SaaS
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%.
(Starting MRR − contraction − churn) ÷ starting MRR × 100%
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.
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.
SQL & 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.
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;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
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.
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.
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.
With the built-in Targets app you set a target for the KPI per month, so you see actuals and target side by side.
FAQ
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%.
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.
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.
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.