Skip to content

All projects

SaaS Revenue Metrics Warehouse

Synthetic benchmark Synthetic data: Ledgerly

A dbt and DuckDB warehouse that turns raw contract data into ARR, the MRR bridge, net and gross revenue retention, cohorts and bookings, with every metric defined in writing and backed by tests.

Status
Code on GitHub
Relevant to
Data and analytics, GTM Systems
Code
github.com/jungmarker/saas-revenue-metrics

Results · Synthetic data: Ledgerly

  • in SMB, hidden inside a healthy 105% company NRRSynthetic benchmark
  • comes from 44 Enterprise accountsSynthetic benchmark
  • models and tests pass in about 2 secondsImplementation fact

At a glance

Question
How do you define ARR, retention and the MRR bridge so two teams get the same number?
Data
Ledgerly’s raw contract exports (synthetic).
How it was tested
Written definitions plus dbt tests that fail the build if the MRR bridge doesn’t balance or if MRR recomputed from contract lines disagrees.
Result
The models and tests pass, and the contract-line test caught a real bug in the upstream data generator. In the data, a healthy 105% company NRR hides 84% NRR and 69% GRR in SMB.
What it doesn’t show
The contracts are synthetic, so the business findings describe Ledgerly. What carries over is the tested definitions and tie-outs.
Revenue dashboard with ARR, MRR bridge and retention
Revenue dashboard with ARR, MRR bridge and retention

The problem

Revenue metrics look simple until two teams report two different ARR numbers. The hard part is agreeing on definitions and proving the numbers tie out.

What I built, in detail

  • Staging, intermediate and mart models on Ledgerly’s raw exports, including an account × month MRR grid with $0 months so churn is detectable.
  • Written definitions for MRR, ARR, NRR, GRR, logo churn, quick ratio, ARPA, cohort retention and bookings.
  • A test that fails the build if starting MRR plus movements doesn’t equal ending MRR, and a second test that recomputes MRR straight from contract lines.
  • A one-page read for a leadership team on what the numbers say.

How I checked it

  • The contract-line tie-out test caught a real bug in the upstream data generator: renewals due in the final month were being counted as churn.

Stack

dbt, DuckDB, SQL, Python, Chart.js, GitHub Actions