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
Results · Synthetic data: Ledgerly
- Synthetic benchmarkSynthetic data: Ledgerly. Measured against a hidden answer key in that data. It shows the method works there, not a production result.in SMB, hidden inside a healthy 105% company NRRSynthetic benchmark
- Synthetic benchmarkSynthetic data: Ledgerly. Measured against a hidden answer key in that data. It shows the method works there, not a production result.comes from 44 Enterprise accountsSynthetic benchmark
- Implementation factA fact about what was built and tested, not a business outcome.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.

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