Methodology
Cash Runway Planner methodology
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
netCashFlow = recurringInflows + oneOffInflows − recurringOutflows − oneOffOutflowsWhere
- 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
closingCash = priorClosingCash + netCashFlowWhere
- 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
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
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
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
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
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
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
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
runwayDate = firstBufferBreachDateWhere
- 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
averageCadenceDays = observedDays ÷ periodCountWhere
- 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
netBurnPerDay = sum(−netCashFlow) ÷ observedDaysWhere
- 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
runwayDays = max(0, openingCash − minimumCashBuffer) ÷ netBurnPerDayWhere
- 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
baseRunwayDays = runwayDaysWhere
- 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
basePeakFundingGap = peakFundingGapWhere
- 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
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
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
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
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
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
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
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
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.grossBurnPerPeriod = burn.recurringOutflowsPerPeriodWhere
- 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.netBurnPerPeriod = burn.recurringOutflowsPerPeriod − burn.recurringInflowsPerPeriodWhere
- 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.adjustedNetBurnPerPeriod = burn.netBurnPerPeriod + burn.oneOffOutflowsInHorizon ÷ burn.horizonPeriodsWhere
- 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.runwayPeriods = (burn.openingCash − burn.minimumCashBuffer) ÷ burn.adjustedNetBurnPerPeriodWhere
- 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.horizonClosingCash = burn.openingCash − burn.adjustedNetBurnPerPeriod × burn.horizonPeriodsWhere
- 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
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
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
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
troughClosingCash = min(closingCash)Where
- closingCash
- Closing cash (currency units)Source: Calculated output
endingCash = finalClosingCashWhere
- finalClosingCash
- Final closing cash (currency units)Source: Calculated output
coverageMethodReserve = essentialOutflowsPerPeriod × targetCoveragePeriods + knownOneOffOutflowsWhere
- 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
reserveTarget = max(coverageMethodReserve, seasonalScenarioReserve)Where
- coverageMethodReserve
- Coverage-method reserve (currency units)Source: Calculated output
- seasonalScenarioReserve
- Seasonal-scenario reserve (currency units)Source: Calculated output
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
currentReserveGap = max(0, reserveTarget − currentReserve)Where
- currentReserve
- Module current reserve (currency units)Source: Business record
- reserveTarget
- Transparent reserve target (currency units)Source: Calculated output
currentReserveSurplus = max(0, currentReserve − reserveTarget)Where
- currentReserve
- Module current reserve (currency units)Source: Business record
- reserveTarget
- Transparent reserve target (currency units)Source: Calculated output
coveredEssentialOutflowPeriods = max(0, currentReserve − knownOneOffOutflows) ÷ essentialOutflowsPerPeriodWhere
- 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
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
- : Initial public release of the planner and methodology after pre-launch calculation, content, source and interaction review.
Related reading
Guides to interpret the decision and its assumptions.
- How to Write a Cash-Buffer Policy for a Micro-Business
Write a reviewable cash-buffer policy from dated outflows, disruption scenarios, draw rules and replenishment triggers without a generic reserve benchmark.
Read guide - Plan Cash for a Seasonal Trough
Build a dated weekly baseline and lower-receipts case through the trough using a user-chosen cash floor.
Read guide