At a glance
- Level
- Beginner
- Time
- 22 min
Prerequisites
- Read access to your billing data (Stripe, Paddle or a subscriptions table)
- A general ledger export or connection (QuickBooks or Xero)
- CRM opportunities (HubSpot or Salesforce) for pipeline coverage
- A Postgres-compatible warehouse, or Kimo connected to the sources above
You will end up with
A written, versioned definition and a working Postgres query for each of the ten metrics boards and investors ask for, ready to promote into certified Kimo measures.
Connectors used
Every board meeting eventually reaches the same moment: someone asks why the net revenue retention on slide 6 does not match the figure in last quarter’s investor update. The answer is almost never fraud and rarely a bug. It is two people computing the same name with different rules: one includes a reactivated customer as “new”, the other as “expansion”; one annualizes a usage spike, the other does not. The fix is boring and effective: one written definition per metric, implemented once, reused everywhere.
Public companies are held to this standard already. The SEC’s 2020 guidance on key performance indicators asks issuers to give a clear definition of each metric and how it is calculated, to disclose changes in methodology and their effects, and to consider recasting prior periods when the method changes.1Source 1 · U.S. Securities and Exchange Commission, Federal Register, 2020Commission Guidance on Management’s Discussion and Analysis of Financial Condition and Results of Operations (Release 33-10751)govinfo.gov Private companies are not bound by that release, but investors running diligence apply the same logic. If you adopt it early, the data room almost builds itself.
What makes a metric definition board-grade?
A board-grade definition answers six questions. If any answer is “it depends”, the metric will drift between reports.
| Element | Question it answers | Example for MRR |
|---|---|---|
| Name and owner | Who decides if the rule changes? | MRR, owned by the finance lead |
| Grain | What is one row? | One customer, one calendar month (measured at month end) |
| Inclusions | What counts? | Active and past-due recurring subscriptions |
| Exclusions | What never counts? | Trials, taxes, one-time fees, metered usage |
| Source of truth | Which system wins a dispute? | Billing system (Stripe), reconciled monthly to the ledger |
| Reference query | How exactly is it computed? | The mrr_monthly view below, version-controlled |
In Kimo, these six elements live on the measure itself in the semantic layer: name, owner, filters, description, source model and the generated SQL. See measures and dimensions for the syntax. The rest of this guide stays tool-agnostic.
MRR and ARR: what counts as recurring revenue?
Stripe’s own Billing analytics follow this logic: MRR is the sum of the monthly-normalized value of active and past-due subscriptions; taxes, free plans and metered (usage-based) products are excluded; and a yearly plan contributes one twelfth of its price each month. Stripe’s worked example is 100 subscribers at $100 per month plus 50 subscribers at $600 per year, which equals $12,500 of MRR.2Source 2 · Stripe DocumentationBilling analytics: metric definitions (MRR, MRR growth, churn, LTV)docs.stripe.com Stripe also lets you choose whether to subtract discounts and calls subtracting them the more conservative approach.2Source 2 · Stripe DocumentationBilling analytics: metric definitions (MRR, MRR growth, churn, LTV)docs.stripe.com
The most common error is treating ARR as annual run rate. Andreessen Horowitz is explicit: in software, ARR means annual recurring revenue, and it is a mistake to multiply a month’s recognized bookings or revenue by 12 and call it ARR,4Source 4 · Andreessen Horowitz, 201516 More Startup Metricsa16z.com and one-time and professional services fees stay out.3Source 3 · Andreessen Horowitz, 201516 Startup Metricsa16z.com Variable usage stays out too, consistent with Stripe’s exclusion of metered products.2Source 2 · Stripe DocumentationBilling analytics: metric definitions (MRR, MRR growth, churn, LTV)docs.stripe.com Bookings are not revenue either: a booking is the value of a contract with the customer, while revenue is recognized as the service is provided or ratably over the subscription.3Source 3 · Andreessen Horowitz, 201516 Startup Metricsa16z.com Under US GAAP, ASC 606 requires revenue to be recognized to depict the transfer of promised goods or services to customers,5Source 5 · Deloitte DARTRoadmap: Revenue Recognition, 3.1 Objective (ASC 606-10-10-2)dart.deloitte.com which is why ARR is an operating metric, not an accounting one. See the glossary entries for MRR and ARR.
Edge cases to decide in writing
- Past-due invoices. Stripe keeps
past_duesubscriptions in MRR until they are canceled or marked unpaid.2Source 2 · Stripe DocumentationBilling analytics: metric definitions (MRR, MRR growth, churn, LTV)docs.stripe.com Many finance teams add a cutoff (for example, exclude after 30 days past due). Either is fine; mixing them is not. - Multi-year contracts with ramps. Count the MRR in force for the current period, not the average over the term.
- Usage and overages. Exclude by default. If usage is a large, stable share of revenue, report it as a separate line (“committed ARR” vs. “usage revenue”) rather than folding it in.
- Currency. Convert at a fixed rate per reporting period and disclose the rate, so FX swings do not masquerade as churn or expansion.
- Signed but not live. Contracted-not-started deals belong in a separate “contracted ARR” or backlog figure, never in ARR.
-- Month-end MRR per customer, normalized to a monthly amount.
-- subscriptions: id, customer_id, status, billing_interval ('month' | 'year'),
-- unit_amount_cents, quantity, pricing_model ('licensed' | 'metered'),
-- is_trial, started_at, ended_at
create or replace view mrr_monthly as
with months as (
select generate_series(
date '2024-01-01',
date_trunc('month', current_date)::date,
interval '1 month'
)::date as month_start
)
select
m.month_start,
s.customer_id,
sum(
case s.billing_interval
when 'month' then s.unit_amount_cents * s.quantity
when 'year' then s.unit_amount_cents * s.quantity / 12.0
end
) / 100.0 as mrr
from months m
join subscriptions s
on s.started_at < m.month_start + interval '1 month'
and (s.ended_at is null or s.ended_at >= m.month_start + interval '1 month')
where s.is_trial = false
and s.pricing_model = 'licensed' -- metered usage stays out of MRR
-- history comes from started_at / ended_at, not from today's status
group by m.month_start, s.customer_id
having sum(s.unit_amount_cents * s.quantity) > 0;The query uses Postgres generate_series with a timestamp and an interval step to build a month spine, and date_trunc to align the current date to the first of the month.6Source 6 · PostgreSQL DocumentationSet Returning Functions (generate_series)postgresql.org7Source 7 · PostgreSQL DocumentationDate/Time Functions and Operators (date_trunc)postgresql.org A customer counts in a month if their subscription is live at the end of that month. ARR is simply 12 * sum(mrr) for a given month_start.
How do you build an MRR bridge that reconciles?
An MRR bridge (or roll-forward) explains the change between two months: starting MRR + new + expansion − contraction − churn = ending MRR. Stripe’s MRR growth metric follows the same structure, with reactivations and a foreign-exchange adjustment as extra lines.2Source 2 · Stripe DocumentationBilling analytics: metric definitions (MRR, MRR growth, churn, LTV)docs.stripe.com Because each customer is classified by comparing two consecutive rows of mrr_monthly, the bridge always sums back to the ending balance. If it does not, you have a duplicate customer ID, not a math problem.
create or replace view mrr_bridge as
with pairs as (
select
coalesce(cur.customer_id, prev.customer_id) as customer_id,
coalesce(cur.month_start, (prev.month_start + interval '1 month')::date) as month_start,
coalesce(prev.mrr, 0) as prev_mrr,
coalesce(cur.mrr, 0) as cur_mrr
from mrr_monthly cur
full outer join mrr_monthly prev
on prev.customer_id = cur.customer_id
and prev.month_start = (cur.month_start - interval '1 month')::date
)
select
month_start,
sum(prev_mrr) as starting_mrr,
sum(case when prev_mrr = 0 and cur_mrr > 0 then cur_mrr else 0 end) as new_mrr,
sum(case when prev_mrr > 0 and cur_mrr > prev_mrr then cur_mrr - prev_mrr else 0 end) as expansion_mrr,
sum(case when prev_mrr > 0 and cur_mrr between 0.01 and prev_mrr - 0.01
then prev_mrr - cur_mrr else 0 end) as contraction_mrr,
sum(case when prev_mrr > 0 and cur_mrr = 0 then prev_mrr else 0 end) as churned_mrr,
sum(cur_mrr) as ending_mrr
from pairs
where month_start <= date_trunc('month', current_date)::date
group by month_start;- New
- Expansion
- Contraction
- Churn
Net revenue retention vs. gross revenue retention
Net revenue retention (NRR) measures how much recurring revenue a fixed group of customers generates today compared with a year ago, including expansion. Gross revenue retention (GRR) measures the same group but caps each customer at their starting value, so expansion cannot hide churn. Andreessen Horowitz makes the same distinction for churn: gross churn estimates the actual loss to the business, while net revenue churn understates losses because upsells are blended in.3Source 3 · Andreessen Horowitz, 201516 Startup Metricsa16z.com
NRR=MRR today from customers active 12 months ago ÷ their MRR 12 months ago
- Cohort
- Customers with MRR > 0 at the start month; new customers since then are excluded.
- Churned customers
- Stay in the denominator and contribute 0 to the numerator.
GRR=Σ min(MRR today, MRR 12 months ago) ÷ Σ MRR 12 months ago
- min()
- Caps each customer at their starting MRR, so GRR can never exceed 100%.
There is no single official formula. Snowflake, for instance, discloses a net revenue retention rate built on a two-year window of product revenue from a fixed customer cohort, keeps churned customers in at zero, and documents the rule in the key business metrics section of its annual report.8Source 8 · U.S. Securities and Exchange Commission (EDGAR), 2025Snowflake Inc. Annual Report on Form 10-K, fiscal year ended January 31, 2025sec.gov That is the point: a good definition says which window, which revenue line and which cohort rule it uses. For context on ranges, Bessemer’s Scaling to $100 Million reported median net retention of 125% for cloud companies at $1–10M ARR and gross retention that stays relatively consistent at 85–90% across scale.9Source 9 · Bessemer Venture Partners, 2021Scaling to $100 Millionbvp.com
with base as (
select customer_id, mrr
from mrr_monthly
where month_start = date '2025-09-01'
),
today as (
select customer_id, mrr
from mrr_monthly
where month_start = date '2026-09-01'
)
select
round(sum(coalesce(t.mrr, 0)) / sum(b.mrr), 4) as nrr,
round(sum(least(coalesce(t.mrr, 0), b.mrr)) / sum(b.mrr), 4) as grr,
count(*) filter (where t.customer_id is null) as churned_logos
from base b
left join today t using (customer_id);Read more in the glossary entries for net revenue retention, gross revenue retention and cohort analysis.
Gross margin: which costs belong in COGS?
Gross margin=(Revenue − Cost of revenue) ÷ Revenue
- Revenue
- GAAP revenue for the period from the ledger, not ARR.
- Cost of revenue
- Hosting, third-party software embedded in the product, payment processing, customer support and onboarding.
Andreessen Horowitz recommends including all costs associated with the manufacturing, delivery and support of a product or service.3Source 3 · Andreessen Horowitz, 201516 Startup Metricsa16z.com The usual disagreements are customer success (support belongs in COGS; expansion-focused account management usually sits in sales and marketing) and R&D infrastructure such as staging environments (not COGS). Bessemer’s benchmark puts the average gross margin for cloud businesses at roughly 65–70%, with the middle half of companies between about 60% and 80%.9Source 9 · Bessemer Venture Partners, 2021Scaling to $100 Millionbvp.com
-- ledger_lines: period_month, account_code, category ('revenue' | 'cogs' | 'opex_sm' | ...), amount
select
date_trunc('quarter', period_month)::date as quarter,
sum(amount) filter (where category = 'revenue') as revenue,
sum(amount) filter (where category = 'cogs') as cost_of_revenue,
round(1 - sum(amount) filter (where category = 'cogs')
/ nullif(sum(amount) filter (where category = 'revenue'), 0), 4) as gross_margin
from ledger_lines
group by 1
order by 1;CAC payback: how many months to earn back acquisition cost?
CAC payback (months)=Sales & marketing expense (prior period) ÷ (New + expansion MRR in period × Gross margin)
- Sales & marketing expense
- Fully loaded: salaries, commissions, tools, paid media, events. Use the prior quarter to reflect the lag between spend and bookings.
- Gross margin
- Trailing gross margin from the ledger, as a fraction.
Bessemer defines CAC payback as the time it takes a customer to repay the cost of acquiring them, counts sales, marketing and the renewal or upsell portion of customer success in acquisition cost, and measures payback against gross-margin-adjusted revenue. Its guidance is under 12 months for SMB, under 18 for mid-market and under 24 for enterprise.9Source 9 · Bessemer Venture Partners, 2021Scaling to $100 Millionbvp.com Some teams use new MRR only in the denominator; others include expansion because expansion also consumes sales capacity. Both are defensible; switching between them quarter to quarter is not. Glossary: CAC payback.
with sm as (
select date_trunc('quarter', period_month)::date as quarter, sum(amount) as sm_expense
from ledger_lines where category = 'opex_sm' group by 1
),
gm as (
select date_trunc('quarter', period_month)::date as quarter,
1 - sum(amount) filter (where category = 'cogs')
/ nullif(sum(amount) filter (where category = 'revenue'), 0) as gross_margin
from ledger_lines group by 1
),
growth as (
select date_trunc('quarter', month_start)::date as quarter,
sum(new_mrr + expansion_mrr) as gross_new_mrr
from mrr_bridge group by 1
)
select g.quarter,
round(prev_sm.sm_expense / nullif(g.gross_new_mrr * gm.gross_margin, 0), 1) as cac_payback_months
from growth g
join gm on gm.quarter = g.quarter
join sm prev_sm on prev_sm.quarter = (g.quarter - interval '3 months')::date
order by g.quarter;Burn multiple and runway
David Sacks introduced the burn multiple in 2020 as net burn divided by net new ARR: how much a startup burns to add each incremental dollar of ARR. Lower is better. He described roughly 2x as reasonable for an early-stage startup and argued that the multiple should approach zero over time.10Source 10 · David Sacks (Craft Ventures), 2020The Burn Multiplesacks.substack.com
Burn multiple=Net burn ÷ Net new ARR (same period)
- Net burn
- Cash out minus cash in from operations and capital expenditure, excluding equity and debt financing.
- Net new ARR
- 12 × (new + expansion − contraction − churned MRR) over the period.
Runway (months)=Cash and equivalents ÷ Average monthly net burn (trailing 3 months)
Andreessen Horowitz calls net burn the true measure of how much cash a company burns each month, and notes that investors focus on it to judge how long remaining cash will last.3Source 3 · Andreessen Horowitz, 201516 Startup Metricsa16z.com Compute net burn from the cash ledger, not from the P&L: annual prepayments, capitalized costs and payroll timing make them diverge. If you have committed but undrawn debt, show runway with and without it. Glossary: burn multiple, runway.
-- cash_movements: month, category ('operating' | 'capex' | 'financing'), amount (+ in, - out)
-- cash_balances: month_end, balance
with burn as (
select month, -sum(amount) as net_burn
from cash_movements
where category in ('operating', 'capex')
group by month
),
nna as (
select month_start as month,
12 * (new_mrr + expansion_mrr - contraction_mrr - churned_mrr) as net_new_arr
from mrr_bridge
)
select
date_trunc('quarter', b.month)::date as quarter,
round(sum(b.net_burn) / nullif(sum(n.net_new_arr), 0), 2) as burn_multiple
from burn b
join nna n on n.month = b.month
group by 1
order by 1;
-- Runway at the latest month end
select round(cb.balance / nullif(avg(b.net_burn), 0), 1) as runway_months
from cash_balances cb
join burn b on b.month > cb.month_end - interval '3 months' and b.month <= cb.month_end
where cb.month_end = (select max(month_end) from cash_balances)
group by cb.balance;Rule of 40: growth plus profit
Brad Feld wrote up the rule in 2015, crediting it to a late-stage investor: a SaaS company’s growth rate plus its profit should add up to 40%. He framed it for companies at scale (at least $50 million in revenue), measured growth as year-over-year MRR growth, favored EBITDA as the baseline profit measure and noted that the right profit measure depends on the business.11Source 11 · Brad Feld (feld.com), 2015The Rule of 40% For a Healthy SaaS Companyfeld.com Early-stage teams still report it because boards use it to frame the growth-versus-efficiency trade-off. Write down which growth (year-over-year ARR or revenue) and which margin (EBITDA or free cash flow) you use.
Rule of 40 score=YoY ARR growth % + EBITDA margin % (or free-cash-flow margin %)
Glossary: Rule of 40.
LTV:CAC and pipeline coverage
LTV:CAC compares the gross profit a customer generates over their lifetime with the cost to acquire them. Stripe estimates subscriber LTV as ARPU divided by subscriber churn rate;2Source 2 · Stripe DocumentationBilling analytics: metric definitions (MRR, MRR growth, churn, LTV)docs.stripe.com for board use, multiply by gross margin so you compare profit with cost. Bessemer recommends investing in acquisition when LTV/CAC is 3x or higher.9Source 9 · Bessemer Venture Partners, 2021Scaling to $100 Millionbvp.com Be cautious with young companies: a churn rate measured over a few months turns into a lifetime estimate of many years. Glossary: LTV:CAC ratio.
LTV:CAC=(ARPU × Gross margin ÷ Monthly revenue churn rate) ÷ CAC per new customer
Pipeline coverage tells the board whether next quarter’s plan is reachable. It is an operating convention rather than a standard, so the definition matters even more: which stages count as qualified, whether amounts are weighted by probability, and which close dates are in scope.
Pipeline coverage=Open qualified pipeline with close date in period ÷ Remaining new-bookings target for period
-- crm_opportunities: id, stage, is_closed, amount_arr, close_date
-- bookings_targets: quarter, new_arr_target
with q as (select date_trunc('quarter', current_date)::date as quarter),
won as (
select sum(amount_arr) as won_arr
from crm_opportunities, q
where stage = 'closed_won' and date_trunc('quarter', close_date) = q.quarter
),
open_pipe as (
select sum(amount_arr) as open_arr
from crm_opportunities, q
where is_closed = false
and stage in ('qualified', 'proposal', 'negotiation')
and date_trunc('quarter', close_date) = q.quarter
)
select round(open_pipe.open_arr / nullif(t.new_arr_target - won.won_arr, 0), 2) as coverage
from bookings_targets t, q, won, open_pipe
where t.quarter = q.quarter;Reference table: every definition on one page
| Metric | Formula (short) | Primary source system | Common trap |
|---|---|---|---|
| MRR / ARR | Σ monthly-normalized recurring subscriptions; ARR = 12 × MRR | Billing (Stripe, Paddle) | Annualizing a month of revenue or usage |
| NRR | Cohort MRR now ÷ cohort MRR 12 months ago | Billing | Dropping churned customers from the cohort |
| GRR | Σ min(now, then) ÷ Σ then | Billing | Netting contraction against expansion |
| Gross margin | (Revenue − COGS) ÷ Revenue | Ledger (QuickBooks, Xero) | Leaving support or hosting out of COGS |
| CAC payback | Prior S&M ÷ (gross new MRR × GM) | Ledger + billing | Ignoring gross margin |
| Burn multiple | Net burn ÷ net new ARR | Bank / cash ledger + billing | Using P&L loss instead of cash burn |
| Runway | Cash ÷ avg 3-month net burn | Bank / cash ledger | Counting undrawn debt without saying so |
| Rule of 40 | Growth % + margin % | Billing + ledger | Changing the margin measure between quarters |
| LTV:CAC | Gross-margin LTV ÷ CAC | Billing + ledger | Extrapolating short churn history |
| Pipeline coverage | Qualified open pipeline ÷ remaining target | CRM (HubSpot, Salesforce) | Including unqualified or slipped deals |
Defining the metrics once in Kimo
The queries above are the reference implementation. In Kimo, you promote each one into a certified measure so that dashboards, Ask Kimo and the board deck generator all read the same definition. The SaaS metrics template ships these measures pre-built against Stripe, QuickBooks or Xero, and HubSpot or Salesforce.
model: mrr_monthly
source: warehouse.mrr_monthly
grain: [customer_id, month_start]
owner: finance
measures:
mrr:
type: sum
sql: mrr
format: currency
description: Month-end MRR. Excludes trials, taxes, one-time and metered fees.
certified: true
arr:
type: derived
sql: 12 * {mrr}
format: currency
certified: true
net_revenue_retention:
type: cohort_ratio
cohort: customers with mrr > 0 at period_start - 12 months
numerator: "{mrr}"
denominator: "{mrr} at cohort_start"
format: percent
certified: true
dimensions:
month: { sql: month_start, type: time }
plan: { sql: plan_name }Definition sign-off checklist
- Each metric has a named owner and a one-paragraph written definition.
- Inclusions and exclusions are listed explicitly (trials, taxes, usage, services, discounts, FX).
- The MRR bridge sums to ending MRR every month with zero unexplained difference.
- ARR at quarter end is within an agreed tolerance of ledger subscription revenue × 12 (document the gap).
- Efficiency metrics state their variant (new vs. new + expansion; EBITDA vs. FCF margin).
- Any change in method is logged with a date, a reason and a recast of prior periods.
Next steps: generate a deck from these measures with Build your board deck from live data, or read the full framework in The Board Pack Playbook.
Sources
11 references- Commission Guidance on Management’s Discussion and Analysis of Financial Condition and Results of Operations (Release 33-10751) (opens in a new tab)U.S. Securities and Exchange Commission, Federal Register2020govinfo.gov
Clear definition and calculation of KPIs; disclosing and recasting methodology changes; controls over metrics.
- Billing analytics: metric definitions (MRR, MRR growth, churn, LTV) (opens in a new tab)Stripe Documentationdocs.stripe.com
MRR inclusions and exclusions, annual-plan normalization example, discounts, MRR growth components, LTV formula.
- 16 Startup Metrics (opens in a new tab)Andreessen Horowitz2015a16z.com
ARR exclusions, bookings vs. revenue, gross vs. net churn, gross profit costs, net burn.
- 16 More Startup Metrics (opens in a new tab)Andreessen Horowitz2015a16z.com
ARR is annual recurring revenue, not annual run rate.
- Roadmap: Revenue Recognition, 3.1 Objective (ASC 606-10-10-2) (opens in a new tab)Deloitte DARTdart.deloitte.com
Core principle of ASC 606.
- Set Returning Functions (generate_series) (opens in a new tab)PostgreSQL Documentationpostgresql.org
- Date/Time Functions and Operators (date_trunc) (opens in a new tab)PostgreSQL Documentationpostgresql.org
- Snowflake Inc. Annual Report on Form 10-K, fiscal year ended January 31, 2025 (opens in a new tab)U.S. Securities and Exchange Commission (EDGAR)2025sec.gov
Example of a disclosed net revenue retention methodology.
- Scaling to $100 Million (opens in a new tab)Bessemer Venture Partners2021bvp.com
CAC payback definition and segment benchmarks; NRR, GRR and gross margin benchmarks; LTV/CAC 3x.
- The Burn Multiple (opens in a new tab)David Sacks (Craft Ventures)2020sacks.substack.com
- The Rule of 40% For a Healthy SaaS Company (opens in a new tab)Brad Feld (feld.com)2015feld.com
External sources were accessed at the time of writing. Kimo product details, customers and figures in examples are illustrative unless a source is cited.
Mark as done
0 of 11 sections done
Frequently asked questions
Is ARR the same as annual revenue?
No. ARR is a point-in-time operating metric: current recurring subscriptions normalized to a year. Annual revenue is the GAAP revenue recognized over a fiscal year. A growing company’s year-end ARR is usually higher than its revenue for that year.
Should usage-based revenue be included in ARR?
By default, no: variable usage fees are excluded from ARR. If usage is large and stable, report committed ARR and trailing usage revenue as two separate lines and explain the split.
Why can NRR be above 100% while GRR is not?
NRR counts expansion from existing customers, so upsells can more than offset churn. GRR caps each customer at their starting revenue, so it can only measure what was kept, never what was added.
Which period should I use for CAC payback?
Quarterly, with sales and marketing expense from the prior quarter, is the most common choice because it smooths monthly noise and reflects the lag between spend and bookings. State the choice in the definition.
What is a good burn multiple?
David Sacks described about 2x as reasonable for an early-stage startup and argued that the multiple should approach zero over time. Compare against your own trend first.
Skip the setup — start from a working version.
SaaS metrics: ARR, NRR, GRR, CAC payback, burn multiple and runway on one governed model.


