Skip to main content

Methodology

Cash Runway Planner methodology

Identify dated cash-buffer breaches and funding gaps across exact Base, Downside and Action runway scenarios, with an independent burn-rate summary module.

Educational only: Business decision support, not accounting, tax or legal advice.

Privacy: Calculations run locally; Margin101 does not receive your commercial inputs.

Update policy: Reviewed when formulas or official dependencies change.

Scope: Market-neutral small-business planning using your own assumptions.

1. Formulas and units

Period net cash flow
netCashFlow = recurringInflows + oneOffInflows − recurringOutflows − oneOffOutflows

Where

recurringInflows
Recurring inflows (currency units per period)Source: Business record
recurringOutflows
Recurring outflows (currency units per period)Source: Business record
oneOffInflows
One-off inflows (currency units)Source: User assumption
oneOffOutflows
One-off outflows (currency units)Source: User assumption
netCashFlow
Net cash flow (currency units)Source: Calculated output
Closing cash
closingCash = priorClosingCash + netCashFlow

Where

priorClosingCash
Prior closing cash (currency units)Source: Calculated output
netCashFlow
Net cash flow (currency units)Source: Calculated output
closingCash
Closing cash (currency units)Source: Calculated output
Buffer gap
bufferGap = max(0, minimumCashBuffer − closingCash)

Where

minimumCashBuffer
Minimum cash buffer (currency units)Source: User decision
closingCash
Closing cash (currency units)Source: Calculated output
bufferGap
Buffer shortfall (currency units)Source: Calculated output
minimumClosingCash
Minimum closing cash (currency units)Source: Calculated output
max
Maximum operator (operator)Source: Calculated output
Minimum closing cash
minimumClosingCash = min(closingCash)

Where

closingCash
Closing cash (currency units)Source: Calculated output
minimumClosingCash
Minimum closing cash (currency units)Source: Calculated output
min
Minimum operator (operator)Source: Calculated output
Peak funding gap
peakFundingGap = max(0, bufferGap, −finalClosingCash)

Where

finalClosingCash
Final closing cash (currency units)Source: Calculated output
closingCash
Closing cash (currency units)Source: Calculated output
bufferGap
Buffer shortfall (currency units)Source: Calculated output
peakFundingGap
Peak funding gap (currency units)Source: Calculated output
max
Maximum operator (operator)Source: Calculated output
fundingGap
Exact funding-gap engine projection (operator)Source: Calculated output
First negative period
firstNegativePeriodId = first(periodId | closingCash < 0)

Where

periodId
Stable generated period identifier (row ID)Source: Calculated output
closingCash
Closing cash (currency units)Source: Calculated output
firstNegativePeriodId
First negative row ID (row ID or not reached)Source: Calculated output
first
First-match operator (operator)Source: Calculated output
First negative date
firstNegativeDate = first(date | closingCash < 0)

Where

date
Period date (ISO date)Source: Business record
closingCash
Closing cash (currency units)Source: Calculated output
firstNegativeDate
First negative date (ISO date or not reached)Source: Calculated output
first
First-match operator (operator)Source: Calculated output
First buffer-breach period
firstBufferBreachPeriodId = first(periodId | closingCash < minimumCashBuffer)

Where

minimumCashBuffer
Minimum cash buffer (currency units)Source: User decision
periodId
Stable generated period identifier (row ID)Source: Calculated output
closingCash
Closing cash (currency units)Source: Calculated output
minimumClosingCash
Minimum closing cash (currency units)Source: Calculated output
firstBufferBreachPeriodId
First buffer-breach row ID (row ID or not reached)Source: Calculated output
first
First-match operator (operator)Source: Calculated output
First buffer-breach date
firstBufferBreachDate = first(date | closingCash < minimumCashBuffer)

Where

minimumCashBuffer
Minimum cash buffer (currency units)Source: User decision
date
Period date (ISO date)Source: Business record
closingCash
Closing cash (currency units)Source: Calculated output
minimumClosingCash
Minimum closing cash (currency units)Source: Calculated output
firstBufferBreachDate
First buffer-breach date (ISO date or not reached)Source: Calculated output
first
First-match operator (operator)Source: Calculated output
Runway date
runwayDate = firstBufferBreachDate

Where

date
Period date (ISO date)Source: Business record
firstBufferBreachDate
First buffer-breach date (ISO date or not reached)Source: Calculated output
runwayDate
Runway date (ISO date or not reached)Source: Calculated output
first
First-match operator (operator)Source: Calculated output
runway
Exact runway engine projection (operator)Source: Calculated output
Average dated cadence
averageCadenceDays = observedDays ÷ periodCount

Where

periodCount
Entered row count (whole periods)Source: Calculated output
observedDays
Total inferred dated duration (calendar days)Source: Calculated output
averageCadenceDays
Average dated cadence (calendar days)Source: Calculated output
Time-weighted net burn
netBurnPerDay = sum(−netCashFlow) ÷ observedDays

Where

observedDays
Total inferred dated duration (calendar days)Source: Calculated output
netCashFlow
Net cash flow (currency units)Source: Calculated output
netBurnPerDay
Time-weighted net burn (currency units per calendar day)Source: Calculated output
sum
Sum operator (operator)Source: Calculated output
Runway above buffer
runwayDays = max(0, openingCash − minimumCashBuffer) ÷ netBurnPerDay

Where

openingCash
Opening cash (currency units)Source: Business record
minimumCashBuffer
Minimum cash buffer (currency units)Source: User decision
netBurnPerDay
Time-weighted net burn (currency units per calendar day)Source: Calculated output
runwayDays
Runway above buffer (calendar days or not reached)Source: Calculated output
max
Maximum operator (operator)Source: Calculated output
runway
Exact runway engine projection (operator)Source: Calculated output
burn.openingCash
Burn module openingCash (currency units)Source: Business record
burn.minimumCashBuffer
Burn module minimumCashBuffer (currency units)Source: User assumption
Base scenario runway
baseRunwayDays = runwayDays

Where

runwayDays
Runway above buffer (calendar days or not reached)Source: Calculated output
baseRunwayDays
Base runway (calendar days or not reached)Source: Calculated output
runway
Exact runway engine projection (operator)Source: Calculated output
Base scenario peak funding gap
basePeakFundingGap = peakFundingGap

Where

peakFundingGap
Peak funding gap (currency units)Source: Calculated output
basePeakFundingGap
Base peak funding gap (currency units)Source: Calculated output
fundingGap
Exact funding-gap engine projection (operator)Source: Calculated output
Downside recurring inflows
downsideRecurringInflows = recurringInflows × (1 − downsideAdjustmentPercent ÷ 100)

Where

recurringInflows
Recurring inflows (currency units per period)Source: Business record
downsideAdjustmentPercent
Downside recurring adjustment (percentage from 0 to 100)Source: User assumption
downsideRecurringInflows
Downside inflows (currency units per period)Source: Calculated output
Downside recurring outflows
downsideRecurringOutflows = recurringOutflows × (1 + downsideAdjustmentPercent ÷ 100)

Where

recurringOutflows
Recurring outflows (currency units per period)Source: Business record
downsideAdjustmentPercent
Downside recurring adjustment (percentage from 0 to 100)Source: User assumption
downsideRecurringOutflows
Downside outflows (currency units per period)Source: Calculated output
Downside scenario runway
downsideRunwayDays = runway(downsideRecurringInflows, downsideRecurringOutflows)

Where

recurringInflows
Recurring inflows (currency units per period)Source: Business record
recurringOutflows
Recurring outflows (currency units per period)Source: Business record
runwayDays
Runway above buffer (calendar days or not reached)Source: Calculated output
downsideRecurringInflows
Downside inflows (currency units per period)Source: Calculated output
downsideRecurringOutflows
Downside outflows (currency units per period)Source: Calculated output
downsideRunwayDays
Downside runway (calendar days or not reached)Source: Calculated output
runway
Exact runway engine projection (operator)Source: Calculated output
Downside scenario peak funding gap
downsidePeakFundingGap = fundingGap(downsideRecurringInflows, downsideRecurringOutflows)

Where

recurringInflows
Recurring inflows (currency units per period)Source: Business record
recurringOutflows
Recurring outflows (currency units per period)Source: Business record
peakFundingGap
Peak funding gap (currency units)Source: Calculated output
downsideRecurringInflows
Downside inflows (currency units per period)Source: Calculated output
downsideRecurringOutflows
Downside outflows (currency units per period)Source: Calculated output
downsidePeakFundingGap
Downside peak funding gap (currency units)Source: Calculated output
fundingGap
Exact funding-gap engine projection (operator)Source: Calculated output
Action recurring inflows
actionRecurringInflows = recurringInflows × (1 + actionAdjustmentPercent ÷ 100)

Where

recurringInflows
Recurring inflows (currency units per period)Source: Business record
actionAdjustmentPercent
Action recurring adjustment (percentage from 0 to 100)Source: User assumption
actionRecurringInflows
Action inflows (currency units per period)Source: Calculated output
Action recurring outflows
actionRecurringOutflows = recurringOutflows × (1 − actionAdjustmentPercent ÷ 100)

Where

recurringOutflows
Recurring outflows (currency units per period)Source: Business record
actionAdjustmentPercent
Action recurring adjustment (percentage from 0 to 100)Source: User assumption
actionRecurringOutflows
Action outflows (currency units per period)Source: Calculated output
Action scenario runway
actionRunwayDays = runway(actionRecurringInflows, actionRecurringOutflows)

Where

recurringInflows
Recurring inflows (currency units per period)Source: Business record
recurringOutflows
Recurring outflows (currency units per period)Source: Business record
runwayDays
Runway above buffer (calendar days or not reached)Source: Calculated output
actionRecurringInflows
Action inflows (currency units per period)Source: Calculated output
actionRecurringOutflows
Action outflows (currency units per period)Source: Calculated output
actionRunwayDays
Action runway (calendar days or not reached)Source: Calculated output
runway
Exact runway engine projection (operator)Source: Calculated output
Action scenario peak funding gap
actionPeakFundingGap = fundingGap(actionRecurringInflows, actionRecurringOutflows)

Where

recurringInflows
Recurring inflows (currency units per period)Source: Business record
recurringOutflows
Recurring outflows (currency units per period)Source: Business record
peakFundingGap
Peak funding gap (currency units)Source: Calculated output
actionRecurringInflows
Action inflows (currency units per period)Source: Calculated output
actionRecurringOutflows
Action outflows (currency units per period)Source: Calculated output
actionPeakFundingGap
Action peak funding gap (currency units)Source: Calculated output
fundingGap
Exact funding-gap engine projection (operator)Source: Calculated output
Burn module: Gross recurring burn
burn.grossBurnPerPeriod = burn.recurringOutflowsPerPeriod

Where

recurringOutflows
Recurring outflows (currency units per period)Source: Business record
burn.recurringOutflowsPerPeriod
Burn module recurringOutflowsPerPeriod (currency units)Source: User assumption
burn.grossBurnPerPeriod
Burn module gross recurring burn (currency units)Source: Calculated output
Burn module: Net recurring burn
burn.netBurnPerPeriod = burn.recurringOutflowsPerPeriod − burn.recurringInflowsPerPeriod

Where

recurringInflows
Recurring inflows (currency units per period)Source: Business record
recurringOutflows
Recurring outflows (currency units per period)Source: Business record
burn.recurringInflowsPerPeriod
Burn module recurringInflowsPerPeriod (currency units)Source: User assumption
burn.recurringOutflowsPerPeriod
Burn module recurringOutflowsPerPeriod (currency units)Source: User assumption
burn.netBurnPerPeriod
Burn module net recurring burn (currency units)Source: Calculated output
Burn module: One-off-adjusted net burn
burn.adjustedNetBurnPerPeriod = burn.netBurnPerPeriod + burn.oneOffOutflowsInHorizon ÷ burn.horizonPeriods

Where

oneOffOutflows
One-off outflows (currency units)Source: User assumption
burn.oneOffOutflowsInHorizon
Burn module oneOffOutflowsInHorizon (currency units)Source: User assumption
burn.horizonPeriods
Burn module horizonPeriods (whole periods)Source: User assumption
burn.netBurnPerPeriod
Burn module net recurring burn (currency units)Source: Calculated output
burn.adjustedNetBurnPerPeriod
Burn module one-off-adjusted net burn (currency units)Source: Calculated output
Burn module: Adjusted runway
burn.runwayPeriods = (burn.openingCash − burn.minimumCashBuffer) ÷ burn.adjustedNetBurnPerPeriod

Where

openingCash
Opening cash (currency units)Source: Business record
minimumCashBuffer
Minimum cash buffer (currency units)Source: User decision
runway
Exact runway engine projection (operator)Source: Calculated output
burn.openingCash
Burn module openingCash (currency units)Source: Business record
burn.minimumCashBuffer
Burn module minimumCashBuffer (currency units)Source: User assumption
burn.netBurnPerPeriod
Burn module net recurring burn (currency units)Source: Calculated output
burn.adjustedNetBurnPerPeriod
Burn module one-off-adjusted net burn (currency units)Source: Calculated output
burn.runwayPeriods
Burn module adjusted runway (periods)Source: Calculated output
Burn module: Horizon closing cash
burn.horizonClosingCash = burn.openingCash − burn.adjustedNetBurnPerPeriod × burn.horizonPeriods

Where

openingCash
Opening cash (currency units)Source: Business record
closingCash
Closing cash (currency units)Source: Calculated output
burn.openingCash
Burn module openingCash (currency units)Source: Business record
burn.horizonPeriods
Burn module horizonPeriods (whole periods)Source: User assumption
burn.netBurnPerPeriod
Burn module net recurring burn (currency units)Source: Calculated output
burn.adjustedNetBurnPerPeriod
Burn module one-off-adjusted net burn (currency units)Source: Calculated output
burn.horizonClosingCash
Burn module horizon closing cash (currency units)Source: Calculated output
Seasonal module required opening reserve
requiredOpeningReserve = minimumCashBalance − min(0, cumulativeNetCashFlow)

Where

minimumCashBalance
Seasonal chosen minimum balance (currency units)Source: User decision
cumulativeNetCashFlow
Cumulative module net cash flow (currency units)Source: Calculated output
Seasonal module additional reserve gap
additionalReserveGap = max(0, requiredOpeningReserve − currentReserve)

Where

currentReserve
Module current reserve (currency units)Source: Business record
requiredOpeningReserve
Seasonal required opening reserve (currency units)Source: Calculated output
Seasonal module trough date
troughDate = first(date | closingCash = troughClosingCash)

Where

date
Period date (ISO date)Source: Business record
closingCash
Closing cash (currency units)Source: Calculated output
troughClosingCash
Seasonal trough closing cash (currency units)Source: Calculated output
Seasonal module trough closing cash
troughClosingCash = min(closingCash)

Where

closingCash
Closing cash (currency units)Source: Calculated output
Seasonal module ending cash
endingCash = finalClosingCash

Where

finalClosingCash
Final closing cash (currency units)Source: Calculated output
Reserve module coverage-method reserve
coverageMethodReserve = essentialOutflowsPerPeriod × targetCoveragePeriods + knownOneOffOutflows

Where

essentialOutflowsPerPeriod
Essential outflows per period (currency units)Source: Business record
targetCoveragePeriods
Chosen coverage periods (periods)Source: User decision
knownOneOffOutflows
Known one-off outflows (currency units)Source: Business record
Reserve module transparent target
reserveTarget = max(coverageMethodReserve, seasonalScenarioReserve)

Where

coverageMethodReserve
Coverage-method reserve (currency units)Source: Calculated output
seasonalScenarioReserve
Seasonal-scenario reserve (currency units)Source: Calculated output
Reserve module seasonal-scenario reserve
seasonalScenarioReserve = minimumOperationalBalance − min(0, cumulativeNetCashFlow)

Where

cumulativeNetCashFlow
Cumulative module net cash flow (currency units)Source: Calculated output
minimumOperationalBalance
Chosen minimum operational balance (currency units)Source: User decision
Reserve module current reserve gap
currentReserveGap = max(0, reserveTarget − currentReserve)

Where

currentReserve
Module current reserve (currency units)Source: Business record
reserveTarget
Transparent reserve target (currency units)Source: Calculated output
Reserve module current reserve surplus
currentReserveSurplus = max(0, currentReserve − reserveTarget)

Where

currentReserve
Module current reserve (currency units)Source: Business record
reserveTarget
Transparent reserve target (currency units)Source: Calculated output
Reserve module covered essential-outflow periods
coveredEssentialOutflowPeriods = max(0, currentReserve − knownOneOffOutflows) ÷ essentialOutflowsPerPeriod

Where

currentReserve
Module current reserve (currency units)Source: Business record
essentialOutflowsPerPeriod
Essential outflows per period (currency units)Source: Business record
knownOneOffOutflows
Known one-off outflows (currency units)Source: Business record
Reserve module trough date
troughDate = first(date | cumulativeNetCashFlow = min(cumulativeNetCashFlow))

Where

date
Period date (ISO date)Source: Business record
cumulativeNetCashFlow
Cumulative module net cash flow (currency units)Source: Calculated output

Money inputs and outputs use the currency selected in the scenario without changing the canonical methodology. Rates, margins, utilisation and buffers are entered as percentages and converted to decimal values for calculation.

2. Worked example

Input assumptions

Every worked value comes from the exact engine and visible default assumptions.

Calculation and outputs

Example

Every worked value comes from the exact engine and visible default assumptions.

Period 1 closing cash
900.00
Period 2 closing cash
200.00
First negative period
Not reached
First negative date
Not reached
First buffer-breach period
period-2
First buffer-breach date
2026-02-28
Runway date
2026-02-28
Minimum closing cash
200.00
Peak funding gap
300.00
Average dated cadence
28 days
Time-weighted net burn per day
14.29
Base scenario runway
35 days
Base scenario peak funding gap
300.00
Downside scenario runway
32.55814 days
Downside scenario peak funding gap
360.00
Action scenario runway
37.837838 days
Action scenario peak funding gap
240.00
Burn module gross recurring burn
3,000.00
Burn module net recurring burn
1,000.00
Burn module one-off-adjusted net burn
2,000.00
Burn module adjusted runway
4 periods
Burn module horizon closing cash
4,000.00
Seasonal module required opening reserve
1,600.00
Seasonal module additional reserve gap
1,100.00
Seasonal module trough date
2026-03-31
Seasonal module trough closing cash
-600.00
Seasonal module ending cash
-300.00
Reserve module coverage-method reserve
35,000.00
Reserve module seasonal-scenario reserve
19,000.00
Reserve module transparent target
35,000.00
Reserve module current reserve gap
15,000.00
Reserve module current reserve surplus
0.00
Reserve module covered essential-outflow periods
1.5 periods
Reserve module trough date
2026-02-28

The exact engine-derived outputs are shown in the labelled rows below.

Interpretation

Use the dated breach and funding gap to compare entered scenarios; it is not a forecast.

3. Validation and boundary checks

  • Two to 52 unique chronological real-date rows are accepted so a dated cadence can be derived.
  • Cash amounts must be finite and non-negative.
  • Downside and Action adjustments must be finite percentages from 0 to 100.
  • Zero or negative time-weighted daily burn returns an explicit unreachable runway.
  • Seasonal and reserve module dates must be real, unique and strictly chronological.
  • Every successful module money output must remain finite; overflow fails closed.

4. Assumptions and source classification

  • Every dated amount, minimum buffer and scenario adjustment is user-entered.
  • The first row duration is inferred from the first two dated endpoints; every later row uses its actual elapsed calendar days.
  • Base preserves entered rows; Downside reduces inflows and raises outflows; Action applies the inverse.
  • The burn-rate module has independent state but inherits this owner methodology.
  • Seasonal and reserve-target modules have independent validated state and inherit this owner methodology, history, trace and PDF.
  • Coverage periods are selected by the user; the model embeds no recommended reserve benchmark.

This planner has no current policy-data dependency. Its commercial assumptions are user supplied. Registered family-level regression suites exercise the shared business-logic engine and worked-result reconciliation.

5. Limitations

  • Named scenarios are deterministic sensitivities, not forecasts.
  • No funding approval, benchmark or tax treatment is inferred.
  • This is educational decision support, not accounting, tax, legal or financial advice.

This is educational decision support, not tax, accounting, legal or financial advice. Check the treatment of your actual transactions under the rules that apply to your business and seek qualified advice where appropriate.

6. Update and evidence policy

Registered family-level suites test formula invariants and example reconciliation; the release ledger records that coverage without claiming a separate oracle for every line of public copy. There is no official threshold or benchmark to refresh for this planner. Commercial inputs remain user-supplied because they vary by business and contract.

Change history

  1. : Initial public release of the planner and methodology after pre-launch calculation, content, source and interaction review.

Guides to interpret the decision and its assumptions.

Return to the planner