SaaS Metrics Simulator

Model SaaS unit economics: calculate LTV, CAC ratio, payback period, MRR growth waterfall, net cash burn, and forecast months of cash runway 100% locally in browser. Every metric shows its formula and an explicit "insufficient input" state instead of a guessed number when required data is missing. Build two named scenarios and compare every metric side by side.

The tabs below edit one connected model for {{ current.name || ('Scenario ' + activeScenario) }} — Monthly Revenue on the Burn tab is derived from the MRR Waterfall's Ending MRR, not a separate number. Switch scenarios here, fill in both, then open Compare A / B.

"Logo churn" = % of customers lost per month (drives LTV/lifetime here). This is deliberately separate from "revenue churn" ($ MRR lost, used in the MRR Waterfall tab) — the two shouldn't be conflated since a low-value customer churning affects logo churn but barely dents revenue churn, and vice versa.

MRR Waterfall Chart

{{ bar.label }}{{ bar.valueLabel }}
= Ending MRR from the Waterfall tab. Edit New/Expansion/Churned MRR there to change it.

Every input and computed metric for both scenarios, side by side. Edit values on the tabs above after switching the active scenario at the top of the page.

LTV (Lifetime Value)
Insufficient input — churn must be > 0%
LTV / CAC Ratio
Insufficient input — CAC must be > 0
CAC Payback Period
Insufficient input — ARPU or margin is 0
Net New MRR
${{ metrics.netNewMrr.toLocaleString() }}
Ending MRR: ${{ metrics.endingMrr.toLocaleString() }} · = New + Expansion − Churned
Annual Run-Rate (ARR)
${{ metrics.calculatedArr.toLocaleString() }}
= Ending MRR × 12
Net Revenue Retention
Insufficient input — Starting MRR must be > 0
Net Monthly Burn
${{ Math.abs(metrics.netBurnRate).toLocaleString() }} /mo
{{ metrics.netBurnRate <= 0 ? 'Cash Flow Positive' : 'Net Cash Outflow' }} · = Expenses − Monthly Revenue (Ending MRR)
Cash Runway
{{ metrics.runwayMonths === Infinity ? '∞' : metrics.runwayMonths }} months
{{ metrics.runwayMonths >= 18 ? '✓ Safe (> 18 mo)' : (metrics.runwayMonths >= 6 ? '⚡ Moderate' : '❌ Critical (< 6 mo)') }}
= Cash ÷ Net Burn

{{ scenarioA.name || 'Scenario A' }} vs {{ scenarioB.name || 'Scenario B' }}

Metric{{ scenarioA.name || 'Scenario A' }}{{ scenarioB.name || 'Scenario B' }}Δ (B − A)
ARPU ($/mo)${{ scenarioA.arpu }}${{ scenarioB.arpu }}{{ scenarioB.arpu >= scenarioA.arpu ? '+' : '' }}${{ scenarioB.arpu - scenarioA.arpu }}
CAC ($)${{ scenarioA.cac }}${{ scenarioB.cac }}{{ scenarioB.cac >= scenarioA.cac ? '+' : '' }}${{ scenarioB.cac - scenarioA.cac }}
Monthly Logo Churn{{ scenarioA.monthlyChurn }}%{{ scenarioB.monthlyChurn }}%{{ (scenarioB.monthlyChurn - scenarioA.monthlyChurn) >= 0 ? '+' : '' }}{{ (scenarioB.monthlyChurn - scenarioA.monthlyChurn).toFixed(1) }}%
LTV{{ metricsA.calculatedLtv !== null ? '$' + metricsA.calculatedLtv.toLocaleString() : 'n/a' }}{{ metricsB.calculatedLtv !== null ? '$' + metricsB.calculatedLtv.toLocaleString() : 'n/a' }}{{ metricsB.calculatedLtv >= metricsA.calculatedLtv ? '+' : '' }}${{ (metricsB.calculatedLtv - metricsA.calculatedLtv).toLocaleString() }}—
LTV / CAC Ratio{{ metricsA.ltvCacRatio !== null ? metricsA.ltvCacRatio + 'x' : 'n/a' }}{{ metricsB.ltvCacRatio !== null ? metricsB.ltvCacRatio + 'x' : 'n/a' }}{{ metricsB.ltvCacRatio >= 3.0 ? '✓ Healthy' : (metricsB.ltvCacRatio >= 1.5 ? '⚡ Moderate' : '❌ Unhealthy') }} n/a
CAC Payback{{ metricsA.paybackMonths !== null ? metricsA.paybackMonths + ' mo' : 'n/a' }}{{ metricsB.paybackMonths !== null ? metricsB.paybackMonths + ' mo' : 'n/a' }}{{ (metricsB.paybackMonths - metricsA.paybackMonths) >= 0 ? '+' : '' }}{{ (metricsB.paybackMonths - metricsA.paybackMonths).toFixed(1) }} mo—
Ending MRR${{ metricsA.endingMrr.toLocaleString() }}${{ metricsB.endingMrr.toLocaleString() }}{{ metricsB.endingMrr >= metricsA.endingMrr ? '+' : '' }}${{ (metricsB.endingMrr - metricsA.endingMrr).toLocaleString() }}
ARR${{ metricsA.calculatedArr.toLocaleString() }}${{ metricsB.calculatedArr.toLocaleString() }}{{ metricsB.calculatedArr >= metricsA.calculatedArr ? '+' : '' }}${{ (metricsB.calculatedArr - metricsA.calculatedArr).toLocaleString() }}
Net Revenue Retention{{ metricsA.nrrPercentage !== null ? metricsA.nrrPercentage + '%' : 'n/a' }}{{ metricsB.nrrPercentage !== null ? metricsB.nrrPercentage + '%' : 'n/a' }}{{ (metricsB.nrrPercentage - metricsA.nrrPercentage) >= 0 ? '+' : '' }}{{ metricsB.nrrPercentage - metricsA.nrrPercentage }}%—
Net Monthly Burn${{ Math.abs(metricsA.netBurnRate).toLocaleString() }}{{ metricsA.netBurnRate <= 0 ? ' (positive)' : '' }}${{ Math.abs(metricsB.netBurnRate).toLocaleString() }}{{ metricsB.netBurnRate <= 0 ? ' (positive)' : '' }}{{ (metricsB.netBurnRate - metricsA.netBurnRate) >= 0 ? '+' : '' }}${{ (metricsB.netBurnRate - metricsA.netBurnRate).toLocaleString() }}
Cash Runway{{ metricsA.runwayMonths === Infinity ? '∞' : metricsA.runwayMonths + ' mo' }}{{ metricsB.runwayMonths === Infinity ? '∞' : metricsB.runwayMonths + ' mo' }}{{ (metricsB.runwayMonths - metricsA.runwayMonths) >= 0 ? '+' : '' }}{{ (metricsB.runwayMonths - metricsA.runwayMonths).toFixed(1) }} mo—

Export {{ exportStatus }}

Exports both scenarios' inputs and computed results (including "insufficient input" markers where applicable). Nothing is sent anywhere — this is a local file download.

About SaaS Metrics Simulator

SaaS Metrics Simulator provides SaaS founders, product engineers, and investors with a financial unit economics calculator. Model customer LTV, CAC payback periods, net revenue retention (NRR), MRR growth waterfalls, and cash runway forecast. Every metric shows its formula, and metrics that can't be computed from the current inputs show an explicit "insufficient input" state rather than a fabricated fallback number.

Named scenarios & comparison: the tool holds two full, independently editable scenarios (default-labelled "Scenario A" / "Scenario B", renameable) instead of one flat set of numbers. Every tab edits whichever scenario is currently active, so LTV/CAC, the MRR waterfall, and burn/runway all move together as one model per scenario — Monthly Revenue on the Burn tab is derived from the MRR Waterfall's Ending MRR rather than being a separate figure you'd have to keep in sync by hand. Use Compare A / B to see every input and computed metric for both scenarios side by side, e.g. an aggressive-spend plan against a conservative one.

Privacy: 100% Client-side. All financial models run locally in your browser memory and are never transmitted to external servers. This is a decision-support estimate, not financial advice.