---
title: "Net revenue retention (NRR): what it measures and what breaks | Skene"
description: "Net revenue retention is the revenue kept from existing customers, expansion included, net of churn. Finance owns the number; product events explain why it moved."
url: https://www.skene.ai/resources/frameworks/net-revenue-retention
doc_version: "51e269c7d116"
last_updated: 2026-10-30
---

Resources / Frameworks

# Net revenue retention: the investor number, and the product events that explain it

Net revenue retention (NRR). Credit: A standard SaaS finance metric with no single originator. By [Teemu Kinos](https://www.skene.ai/about), co-founder of Skene.

Net revenue retention, or NRR, is the revenue a company keeps from an existing group of customers over a period, counting expansion and subtracting churn and downgrades, as a percentage. It is the SaaS health metric investors quote most. A company above 100% grows even if it signs nobody new, and one below 100% has to replace lost revenue before it can grow at all.

## How it works

NRR itself comes from billing, so finance usually owns it and the arithmetic is rarely wrong. What goes wrong is the explanation. When NRR moves, the board asks why, and the answer lives in product data: which accounts expanded, which adopted the features that predict expansion, which went quiet before they churned. If that data is incomplete, the explanation is a guess presented as analysis.

Dave Boyce's _Freemium_ tracks NRR per cohort, assigning each account to the cohort of its first user's activation, and links it to invite data inside the account so that loops bringing colleagues in get credit for the expansion they drive (Ch 12). That gives the board a cause it can check, as long as the invite and seat events are counted.

## What it assumes your events already do

| Event | What the framework uses it for | What it reports when the event breaks |
| --- | --- | --- |
| Plan change `plan_changed` | Expansion and downgrade made in the product. | Self-serve upgrades that bypass the tracked flow appear in billing but not in product data, so expansion is credited to the wrong cause. |
| User-to-account join `account_id on every event` | Matches product usage to the billing account. | A mismatched ID splits one customer into two: one expanding with no usage, one using heavily with no revenue. |
| Invite sent and accepted `invite_sent, invite_accepted` | Seat growth inside the account. | Untracked seat additions hide the loop that drove expansion. |
| Core value action `report_viewed` | Adoption that predicts expansion. | A broken adoption event makes expanding accounts look disengaged, and success teams spend time saving customers who are growing. |

Event names are illustrative; yours will differ. The [dependency map](https://www.skene.ai/resources/frameworks#dependency-map) shows which other frameworks share each event.

## The expansion nobody could explain

_Illustrative example. The company and the figures are invented to show the mechanism._

NRR rises from 104% to 112% over two quarters, and the board asks which features drove it. Product analytics shows no change in adoption of the features the team expected to matter.

After a month of digging, the data team finds that a new in-app seat purchase flow writes to billing directly and fires no product event. The expansion was real and self-serve. For two quarters nobody could see the flow that produced it, so nobody invested in it.

## Checks before you trust it

- Reconcile in-product upgrade and seat events with billing every month, account by account.

- Use one account identifier across billing, CRM and product data.

- Split NRR into expansion, contraction and churn before explaining it; each part has different product drivers.

- Give the explanation an owner, not only the number.

## Check the events under it

Before Net revenue retention (NRR) goes into a plan, find out whether the events it needs exist and still fire the way it assumes. The [free audit](https://www.skene.ai/signup) maps what your product collects today: sign in, connect a GitHub repository or Supabase, and Skene returns one audit, with no card. On Pro, Skene Cloud reviews every pull request on a linked GitHub repository for removed or broken tracking, so a pull request that removes or renames one of these events is flagged before it merges.

## Related

- [The SaaS bowtie: the half of the journey after closed-won](https://www.skene.ai/resources/frameworks/saas-bowtie)

- [Customer health score: a renewal forecast resting on usage events](https://www.skene.ai/resources/frameworks/customer-health-score)

- [Cohort retention analysis: why the blended number hides the trend](https://www.skene.ai/resources/frameworks/cohort-retention-analysis)

- Glossary: [Cohort](https://www.skene.ai/resources/glossary/cohort)

- Glossary: [Payload (event properties)](https://www.skene.ai/resources/glossary/payload)

- Glossary: [Identify call](https://www.skene.ai/resources/glossary/identify-call)

- Glossary: [Event name](https://www.skene.ai/resources/glossary/event-name)

## Sitemap

- [Markdown sitemap](https://www.skene.ai/sitemap.md): every page on this site, with its markdown counterpart.
- [Index for language models](https://www.skene.ai/llms.txt): the same set as a link-dense index.
- [Full corpus](https://www.skene.ai/llms-full.txt): reference content concatenated as plain text.
