MRR Desk

The browser foots the table and measures the retention; the model only names a cause the numbers already allow.

Back to SkillSafe

MRR Desk measures the table you paste, exactly as you paste it. It has no connection to your billing system, it is not financial advice, and it cannot see anything outside that table — a row it cannot read is named and excluded rather than quietly dropped, and a number it cannot compute honestly is refused rather than approximated.

How it works

Nothing to hand? Load the , twelve months across Enterprise, Mid-market and SMB with a cohort triangle, where the segment that moved retention is not the one that lost the most money. Or the , nine months with a residual nothing explains, two joins where the opening does not match the prior close, and churn written negative in two rows. Or the , a five-month table with a two-month gap, a month pasted twice, a subtotal row that is not a month and not one dollar of churn — so the quick ratio and the Rule of 40 are both refused rather than invented. to watch the export refuse itself. All three replay a saved run for free.

1. The table is read, not assumed

Comma, tab, pipe and markdown tables all parse, and a comma inside a quoted cell does not shift the row. Column roles are matched by header name, so the order does not matter and neither do the dozen spellings of “beginning MRR”. The header row is found by the ABSENCE of numbers in it rather than by position, which is what lets a pasted range with a title line, a blank line and a units line above the real header parse without eating a month — and what lets two exports stacked on top of each other read as one book.

2. Nothing is measured until it foots

Every month is re-added from its own components and compared against the stated ending. The tolerance is not a fixed epsilon: it is built from how many decimals the author actually wrote, because a table kept in whole dollars cannot be held to a cent. Then the chain is checked separately — this month's ending against next month's beginning — because a table can foot row by row and still break across the join, which is exactly what a restatement looks like from the outside.

3. The identities are proved, not promised

Net dollar retention minus gross dollar retention has to equal the expansion rate. Counting reactivation has to add exactly the reactivation rate. Gross dollar retention has to be one minus the gross churn rate. The beginning balance plus every movement has to reach the ending balance. Each is computed on both sides and the residual is printed, so you are reading a check that ran rather than a claim in a footnote.

4. The shortcut is shown next to the truth

Lifetime value is computed twice: as the closed-form perpetuity everybody quotes, and as what sixty months of the same curve actually pays. The gap is printed in dollars and as a percentage, because that gap is how a lifetime value ends up several times the truth at a low churn rate. The same is done for the cohort curve against a constant hazard. And the page says plainly that LTV:CAC, the payback and the churn rate are one measurement written three ways, so they cannot corroborate one another.

5. What moved retention is simulated, not sorted

The window is cut in half, each segment — or on an unsegmented table each movement column — is removed in turn, and BOTH halves are re-measured in full. The driver is whichever removal shrinks the change the most. That is a different question from which line lost the most money and routinely has a different answer: a big segment churning steadily loses the most dollars and moves the CHANGE hardly at all. When the top two removals land within a tenth of each other, the engine says the table names no driver rather than picking one.

6. The pass may only name a cause the numbers permit

Before the model runs, the engine decides for each measured fact which causes its own numbers can support, and the model may choose only from that list. Afterwards the same lists check the reply: exactly one cause per fact, counted rather than sampled; any cause not on the admissible list named back by id; any note that merely restates a printed number flagged; every figure traced to something measured at the precision it was written to; and every row the engine had to exclude named by its line number. A fact whose numbers support no cause at all comes back saying so in required words, which one of the bundled books exercises.

Method derived from @wshobson/startup-metrics-framework (wshobson/agents, MIT). MRR Desk is a derived work, not a republication of that skill: the skill spans SaaS, marketplace, consumer and viral pillars as guidance for an agent, while MRR Desk takes only the SaaS revenue-movement and unit-economics pillar and turns it into a deterministic in-browser engine over your own pasted table. The reconciliation tolerance, the printed approximation errors and the removal simulation are this app's own documented extensions.

Questions this app is actually asked

Why print the closed-form lifetime value and the sixty-month one?

Because the closed form is a perpetuity and the business is not. Dividing gross-margin ARPA by the monthly churn rate charges the company for revenue it collects in year eight, year twelve and forever, and at a low churn rate that tail is most of the number. MRR Desk computes the perpetuity, computes what sixty months of the same curve actually pays, and prints the difference in dollars and as a percentage, so the shortcut is visible instead of implied. It also discounts the finite sum, because a dollar collected in month fifty-nine is not a dollar today.

How is the thing that moved retention chosen?

By simulation. The window is cut in half, each segment - or, on an unsegmented table, each movement column - is removed in turn, and BOTH halves are re-measured in full. The driver is whichever removal shrinks the change in net dollar retention the most. That is a different question from which line lost the most money, and it routinely has a different answer: a large segment churning at a steady rate loses the most dollars while contributing almost nothing to the CHANGE, and a smaller segment whose contraction spiked in the second half moves the number. Both are printed with their churn totals so you can see which case you are in. When removing the top part moves the result no further than removing the next one, the engine says the table does not name a driver rather than picking one.

What happens to a number it cannot compute?

It is refused, with a reason, and the refusal is a first-class finding rather than a dash in a cell. A quick ratio in a month with no churn and no contraction divides by zero: that is unbounded, not excellent, and one clean month is not evidence of retention. A burn multiple on a quarter whose net new ARR went backwards would flip sign and read as efficiency. A lifetime value on a book that has not lost a dollar is infinite. A CAC payback with no contribution margin never completes. Each of those comes back as a refusal that says which metric, which period and why.

How does it decide whether my table foots?

Every month is re-added from its own components - beginning plus new plus expansion plus reactivation minus contraction minus churn - and compared against the stated ending. The tolerance is not a fixed epsilon: it is built from the number of decimal places the row was actually written to, summed across the cells that fed the sum, because a table kept in whole dollars cannot honestly be held to a cent while one written to the penny should be. Separately, the chain is checked: this month's ending has to equal next month's beginning. A table can foot row by row and still break across that join, which is what a restatement looks like from the outside, so it is reported as its own finding.

Does it need customer counts or a gross margin?

No, and it does not invent them. Retention, the quick ratio, growth and the whole reconciliation need only the movement columns. Customer counts unlock ARPA, CAC and logo churn; a gross margin unlocks the lifetime value and the payback; S&M spend unlocks the magic number; opex or a net burn unlocks the burn multiple and the Rule of 40. Whatever is missing is refused by name rather than filled with an assumption.

Do I have to sign in?

No. The parsing, the reconciliation, every retention and efficiency metric, the lifetime value and its approximation error, the cohort curve, the driver simulation, the refusals, the whole review, both CSVs, the measurement JSON and every check run in this tab with no account and nothing charged. Only the commentary sentences are metered, and the three bundled books replay a saved run for free.

Why can the download be refused?

Because the thing that must never silently change between the measurement and the file you send to a board is which months were in the window and what each one closed at. Before any export the rendered review is read back, the month ids are collected, and the download is blocked if a month has been lost, listed twice, relabelled to a different month, or had its ending MRR or its retention rate edited. A warning would be cheaper and would also be ignored.

What does a run cost, and what if my balance is low?

A worst-case amount is reserved and only what the run actually uses is charged. The run button is disabled before you submit if the balance cannot cover the model's minimum, and a reply cut short by a low balance says so rather than presenting itself as a complete review.