Here is a scene from almost every Series B company. The CEO opens the board deck: MRR is €1.42M. The VP Sales shares the pipeline review: €1.51M. Finance closes the month at €1.37M. The product dashboard, built two years ago by an intern, says €1.46M. Everyone is right. Nobody is aligned.
This post walks through those four numbers, why each exists, and how to encode them in a metrics layer so that “MRR” on any chart means one documented thing.
The four MRRs
| Definition | Owner | Includes | Excludes |
|---|---|---|---|
| Billing MRR | Product | All active + past-due subscriptions | Nothing — it is raw Stripe |
| Contracted MRR | Sales | Signed contracts, incl. future start dates | Churn notices not yet effective |
| Recognised MRR | Finance | Revenue recognised in the period | Past-due > 30 days, credits, one-offs |
| Normalised MRR | Leadership | Annual plans ÷ 12, FX at budget rate | Discounts flagged as temporary |
- Billing
- Contracted
- Recognised
- Normalised
What a metrics layer actually is
Strip away the vendor vocabulary and a metrics layer is three things: a named measure with an owner, the SQL that computes it from modelled tables, and the dimensions it can legally be sliced by. Tools query the name, not the SQL. That indirection is the whole trick.
Without it, every dashboard embeds its own sum(amount) with its own filters. With it, dashboards say measure: mrr_recognised and the definition lives in one reviewable place.
Encoding one MRR — properly
We recommend picking one default and making the others explicit variants. For most companies the default should be the finance definition, because it is the one that reconciles with the books.
measures:
- name: mrr
label: MRR
description: Recognised MRR. Reconciles with the monthly close.
sql: sum(recognised_amount_monthly)
filters:
- status in ('active', 'past_due')
- days_past_due <= 30
- line_type = 'recurring'
owner: finance
default: true
- name: mrr_contracted
label: MRR (contracted)
description: Signed ARR / 12, including future-dated starts. Sales view.
sql: sum(contract_value_annual) / 12
owner: revopsTwo details matter more than they look. The description is shown in every tooltip and every Ask Kimo answer, so people see what they are reading. And default: true means that when someone asks for “MRR” without qualification, they get the finance number — not whichever one was created first.
The underlying SQL
select
date_trunc('month', p.period_start) as month,
s.customer_id,
s.plan_interval,
case
when s.plan_interval = 'year' then p.amount / 12.0
else p.amount
end as recognised_amount_monthly,
s.status,
greatest(0, current_date - i.due_date) as days_past_due,
p.line_type
from stripe.invoice_lines p
join stripe.subscriptions s on s.id = p.subscription_id
left join stripe.invoices i on i.id = p.invoice_id
where p.line_type = 'recurring';Governance without a committee
The failure mode of metrics layers is not technical, it is social: definitions drift because nobody owns them, or they freeze because everyone must approve a change. A few lightweight rules keep it healthy:
- Every measure has one owner — a team, not a person — who approves changes.
- Changes are versioned and shown as a diff in the activity log, with the before/after value for the last closed month.
- Variants are cheap — creating
mrr_contractedshould take two minutes, so nobody is tempted to fork a dashboard instead. - Deprecate, do not delete — old definitions stay queryable with a warning badge for a quarter.
What changes when it works
The meetings get shorter. The question moves from “whose number is right?” to “why did it move?”, which is the only question worth spending an hour on. And when someone asks Ask Kimo for MRR by region, the answer comes back with a footnote that says exactly which MRR it is.
If you want to see a working revenue model with these definitions, the revenue workspace in the live demo uses the exact structure above on simulated data.
- #Semantic layer
- #MRR
- #Governance
Writes about Fundraising, Board meetings, SaaS metrics, Semantic layer.
People, companies and figures in this article are illustrative; charts use simulated data.




