GASP

Net Revenue Retention (NRR)

Net Revenue Retention (NRR): The percentage of revenue retained from existing customers over a period, including expansion, contraction and churn. Also known as Net Dollar Retention (NDR).

Also known as: NRR, NDR

Formula

NRR = MRR of cohort today / MRR of same cohort 12 months ago × 100
NRR = (Beginning MRR + Expansion MRR - Contraction MRR - Churned MRR) / Beginning MRR × 100
NRR-O = MRR of cohort today (organic only) / MRR of same cohort 12 months ago × 100
NRR-M = (Beginning MRR + All Expansion MRR − Contraction MRR − Churned MRR) / Beginning MRR × 100
NRR-M ≈ NRR-O + Reactivation + Cross-Module + New Buying Centre + Pricing Adjustment + Recontracting expansion

Benchmarks

  • Below 90%: Leaky bucket. Growth requires constant new acquisition.
  • 90-100%: Stable. You keep what you have.
  • 100-110%: Good. Existing customers grow. (Median for VC-backed SaaS: 101-106%)
  • 110-120%: Great. Strong expansion motion.
  • 120%+: Exceptional. Top quartile performance.

What It Tells You

Can you grow without adding new customers? NRR is a critical indicator of SaaS sustainability because it measures whether your existing customer base is expanding or contracting. High NRR reduces dependence on new customer acquisition for growth.

Common Mistakes

  • Calculating over inconsistent time periods
  • Including new customer revenue (that's not NRR)
  • Excluding small customers or segments
  • Confusing with Gross Revenue Retention (GRR)

Dual-Lens: Operating / Market Forms

This metric has two governed forms derived from the same Commercial Event Ledger using Attribution Taxonomy Layer tags.

Operating Form: Cohort NRR (NRR-O)

NRR-O uses the cohort method and includes only organic expansion. Growth from the same product and usage realisation. It excludes expansion from new modules, new buying centres, reactivation and pricing actions.

CEL Source:
`Revenue_Event`
ATL Inclusion:
- `lifecycle_attribution` ∈ (`Retention`, `Expansion`) - `expansion_classification` ∈ (`Same_Product`, `Usage_Realisation`) - Excludes: `expansion_classification` ∈ (`New_Module`, `New_Buying_Centre`, `Pricing_Adjustment`, `Recontracting`) and `lifecycle_attribution` = `Reactivation`
NRR-O = MRR of cohort today (organic only) / MRR of same cohort 12 months ago × 100

What it tells you: True product-market fit signal. Are customers expanding because the product delivers more value, independent of commercial motion?

Market Form: Account NRR (NRR-M)

NRR-M uses the account-level formula method and includes all expansion types. Only net-new logo acquisition is excluded. This matches what public SaaS companies report and what investors benchmark.

CEL Source:
`Revenue_Event`
ATL Inclusion:
- All `expansion_classification` values included - Only `lifecycle_attribution` = `Acquisition` excluded
NRR-M = (Beginning MRR + All Expansion MRR − Contraction MRR − Churned MRR) / Beginning MRR × 100

What it tells you: The total revenue retention and expansion picture that investors use for benchmarking and valuation.

Bridge

NRR-M ≈ NRR-O + Reactivation + Cross-Module + New Buying Centre + Pricing Adjustment + Recontracting expansion

The delta (NRR-M − NRR-O) is the **Expansion Integrity Gap.** How much of reported NRR comes from commercial motion (cross-sell, reactivation, pricing) versus organic product expansion. A wide gap means NRR depends on sales execution rather than product-led growth. Not inherently bad, but the board should know which engine drives retention. SaaS Metrics Standards Board recommends the cohort method. Public SaaS companies report account-level NRR (NRR-M). ---

Adjusted Variant

This metric supports an adjusted form that excludes temporary revenue movements. Tag CEL events with the change_nature field (permanent, temporary, scheduled_reversal) and filter to permanent to compute Adjusted NRR. This separates true contraction (a risk signal) from expected reversals (a neutral event).

See the CEL change_nature spec

Related Metrics

Connected in the GASP relationship graph.

Upstream: what drives this

Downstream: what this drives

Try searching for:

navigateselect