Business Metrics Handbook
Definitive reference for SaaS, e-commerce, and marketplace metrics. Every metric includes a precise definition, SQL formula, Python calculation, industry benchmarks, and common pitfalls. Stop debating metric definitions — standardize on this.
Key Features
- 60+ Metric Definitions — organized by domain: SaaS, e-commerce, marketplace, product, marketing
- SQL Formulas — copy-paste queries for every metric against standard schema
- Python Calculators — reusable functions with type hints and docstrings
- Industry Benchmarks — percentile tables (25th/50th/75th/90th) by company stage
- Metric Trees — visual decomposition showing how metrics relate (e.g., Revenue = Users × ARPU)
- Anti-Patterns — common calculation mistakes and how to avoid them
- Executive Dashboard Spec — recommended metric sets for board decks by business model
Quick Start
from src.saas_metrics import calculate_mrr, calculate_churn, calculate_ltv
# Monthly recurring revenue from subscription data
mrr = calculate_mrr(subscriptions=subscriptions_df, as_of="2025-12-31")
print(f"MRR: ${mrr:,.2f}")
# Logo churn rate
churn = calculate_churn(
start_customers=1200,
end_customers=1150,
new_customers=80,
)
print(f"Monthly churn: {churn:.2%}") # 10.83%
# LTV using churn-based method
ltv = calculate_ltv(arpu=85.00, monthly_churn_rate=churn)
print(f"LTV: ${ltv:,.2f}") # $784.95
Usage Examples
SaaS: Net Revenue Retention (NRR)
-- Net Revenue Retention: expansion + contraction + churn
WITH period AS (
SELECT
DATE_TRUNC('month', period_start) AS month,
SUM(CASE WHEN cohort_month < DATE_TRUNC('month', period_start)
THEN mrr_start END) AS beginning_mrr,
SUM(CASE WHEN expansion_mrr > 0
THEN expansion_mrr ELSE 0 END) AS expansion,
SUM(CASE WHEN contraction_mrr < 0
THEN contraction_mrr ELSE 0 END) AS contraction,
SUM(CASE WHEN churned = TRUE
THEN mrr_start ELSE 0 END) AS churned_mrr
FROM mrr_movements
GROUP BY 1
)
SELECT
month,
ROUND((beginning_mrr + expansion + contraction - churned_mrr)
/ NULLIF(beginning_mrr, 0) * 100, 1) AS nrr_pct
FROM period
ORDER BY month;
-- Benchmark: >100% is good, >120% is elite for B2B SaaS
E-Commerce: CAC Payback
def cac_payback_months(cac: float, avg_monthly_revenue: float,
gross_margin: float) -> float:
"""Calculate months to recover customer acquisition cost.
Args:
cac: Total acquisition cost per customer.
avg_monthly_revenue: Average monthly revenue per customer.
gross_margin: Gross margin as a decimal (e.g., 0.65).
Returns:
Number of months to payback. Target: <12 months.
"""
monthly_gross_profit = avg_monthly_revenue * gross_margin
return cac / monthly_gross_profit
# $150 CAC, $45/mo revenue, 65% margin → 5.1 months payback
print(cac_payback_months(150, 45, 0.65))
Marketplace: Take Rate and GMV
SELECT
category,
SUM(gmv) AS total_gmv,
SUM(platform_revenue) AS total_revenue,
ROUND(SUM(platform_revenue) / NULLIF(SUM(gmv), 0) * 100, 2)
AS take_rate_pct
FROM transactions
WHERE transaction_date >= DATE_TRUNC('quarter', CURRENT_DATE)
GROUP BY category
ORDER BY total_gmv DESC;
-- Benchmark: 10-20% managed marketplaces, 3-8% open marketplaces
Metric Benchmarks (SaaS)
| Metric | 25th Pctile | Median | 75th Pctile | 90th Pctile |
|---|---|---|---|---|
| Monthly Churn | 5.0% | 3.5% | 2.0% | 1.0% |
| Net Revenue Retention | 95% | 105% | 115% | 130% |
| CAC Payback (months) | 18 | 12 | 8 | 5 |
| Gross Margin | 60% | 70% | 78% | 85% |
| LTV:CAC Ratio | 2.0x | 3.0x | 5.0x | 8.0x |
| Rule of 40 Score | 15% | 30% | 45% | 60% |
Configuration
# config.example.yaml
business_model: "saas" # saas | ecommerce | marketplace
currency: "USD"
fiscal_year_start: "01-01" # MM-DD
saas:
contract_basis: "monthly" # monthly | annual | mixed
include_usage_revenue: true # Include metered billing in MRR
expansion_threshold: 0.0 # Min $ change to count as expansion
ecommerce:
attribution_window_days: 30 # For CAC calculations
return_window_days: 30 # Exclude returns within window
Best Practices
- Define metrics once, centrally — disagreements on "how we count churn" waste weeks
- Separate logo churn from revenue churn — they tell different stories
- Use cohorted metrics — blended averages hide trends
- Lag indicators need lead indicators — pair churn with engagement scores
- Benchmark against your stage — Series A benchmarks are irrelevant at Series C
Troubleshooting
| Issue | Cause | Fix |
|---|---|---|
| MRR doesn't match accounting | Deferred vs. recognized revenue | MRR is a SaaS metric, not GAAP; reconcile separately |
| Churn rate >100% monthly | Including downgrades in churn | Separate churn (logo lost) from contraction (downgrade) |
| LTV seems impossibly high | Using revenue not gross profit | LTV = ARPU × Gross Margin / Churn Rate |
| CAC varies wildly by month | Small sample + lumpy ad spend | Use trailing 3-month average |
This is 1 of 11 resources in the Data Analyst Toolkit toolkit. Get the complete [Business Metrics Handbook] with all files, templates, and documentation for $25.
Or grab the entire Data Analyst Toolkit bundle (11 products) for $129 — save 30%.
Top comments (0)