The Short Version

Projections are estimates, not predictions. 7% growth is an average across decades. Your actual returns will swing from -30% to +30% in any given year. The value of projections isn't predicting the future; it's comparing scenarios. "What if I save more?" vs. "What if inflation spikes?" That's the useful question.

Every calculation and default is documented below. Decide if the assumptions fit your situation. For full mathematical derivations and proofs, see Mathematical Foundations.

The Month-by-Month Engine

The projection engine runs a month-by-month simulation. No annual approximations, no shortcuts. For each month in the projection period (by default through the year you turn 90, and at least 30 years), the engine executes these steps in order:

  1. Apply stress test modifiers for the current year (market crash multiplier, growth rate adjustments)
  2. Grow asset balances by their monthly growth rate
  3. Accrue interest on liabilities
  4. Calculate income with annual growth applied
  5. Calculate expenses with per-category inflation applied
  6. Apply stress test multipliers to income and expenses (zeroing income, spiking expenses, inflation overrides)
  7. Make debt payments
  8. Handle contributions or withdrawals depending on accumulation vs. retirement phase
  9. Apply one-time events scheduled for this month
  10. Record the snapshot (balances, totals, deltas, cumulative values)

This produces a time series of monthly snapshots. The answer, the charts, and the Table are read from this data. For setup instructions, see Setting Up Your Profile.

Asset Growth

Formula:

New Balance = Old Balance × (1 + annualRate / 100 / 12)

Growth compounds monthly. The annual rate is divided by 12 to get the monthly rate. Contributions are added after growth is applied.

Example:

Each asset can use the global default growth rate ("market rate") or a custom rate. When stress tests are active, the effective rate may be adjusted (see stress test calculations).

Debt Paydown

Interest accrues first, then the payment is applied:

Interest = Balance × (annualRate / 100 / 12)

New Balance = Balance + Interest - Payment

Example:

First month:

Important: If the monthly payment is less than the monthly interest, the debt grows every month. The engine handles this correctly (balances increase), and the warnings system will flag it.

Income and Expenses

Income Growth

Income streams grow annually by their individual growth rate:

Current Income = Base Amount × (1 + growthRate / 100)yearsElapsed

Example:

Annual amounts are divided by 12 for monthly calculations. Income only applies within its start/end date range. Streams set to "ends at retirement" stop at the retirement date.

Expense Inflation

Same formula, but each category has its own inflation rate:

Current Expense = Base Amount × (1 + inflationRate / 100)yearsElapsed

Healthcare at 5% inflation grows much faster than discretionary spending at 2.5%. Over 20 years, a $500/month healthcare expense becomes $1,327/month. A $300/month discretionary expense becomes $492/month. This is why per-category rates matter.

Surplus Handling

Accumulation phase formula:

Surplus = Tracked Income - Expenses - Debt Payments - Contributions

If surplus is positive and you've picked an account under "Unspent income" in any income form, the extra money is deposited into that account each month. This models automatically investing leftover cash.

If surplus is negative: the shortfall comes out of your savings, in the same order as retirement withdrawals. Contributions count as outflows, so with no income a contribution only moves money from one account to another. If a shortfall empties every account before retirement, the plan counts as failed.

Unspent income: In the income form you choose which asset (one choice for the whole plan) receives surplus deposits. Auto (the default) picks your brokerage, then high-yield savings, then cash, never real estate. With Not invested, surplus is not deposited anywhere. It's just reported in the cash flow tables.

Design choice: The tool doesn't require you to track income and expenses at all. But contributions need income to fund them: without a salary they're treated as transfers between your accounts, not new money. Add your income to see contributions grow your savings.

One-Time Events

Events are applied at step 9 of the monthly loop, after all other calculations. Positive amounts add to an asset balance, negative amounts subtract from it.

Asset targeting: If an event names an account, it's applied there. Otherwise it goes where unspent income goes (with unspent income not invested, to the account it would go to). With no account counted in the plan, it changes no balance.

Examples:

Retirement Withdrawals

When the current date passes your retirement date, the engine switches from accumulation to withdrawal mode. Contributions stop. Instead of depositing surplus, the engine calculates how much to withdraw:

Net Expenses = Monthly Expenses + Debt Payments - Tracked Income

If net expenses are positive (you spend more than you earn), the engine withdraws from your assets to cover the gap. If negative (income exceeds expenses even in retirement), surplus is deposited as before.

Withdrawal Strategy Calculations

Taxable first (default): Assets are sorted by priority:

  1. Taxable brokerage, high-yield savings, cash: priority 1
  2. Retirement accounts (401k, IRA) and HSA: priority 2
  3. Roth (Roth IRA, Roth 401k): priority 3
  4. Everything else (real estate equity, crypto, other): priority 4

The engine drains each account completely before moving to the next priority level. This is sequential depletion: simple and tax-friendly.

Proportional: All eligible accounts are withdrawn from simultaneously, weighted by balance:

Withdrawal from account = Net Expenses × (account balance / total eligible balance)

This maintains your asset allocation through retirement. If your brokerage holds 60% and your 401k holds 40%, you withdraw 60% from brokerage and 40% from 401k.

Custom order: You define the sequence. The engine drains accounts in your specified order, one at a time. Same sequential depletion logic as taxable first, but with your custom ordering.

The 59.5 Penalty-Free Age Rule

When the 59.5 rule is enabled, the engine filters the withdrawal order:

  1. Calculate your current age from birth date
  2. If age < 59.5, exclude retirement account types (retirement, roth, hsa) from eligible assets
  3. Withdraw from remaining accounts normally
  4. If all non-retirement accounts are depleted and you still need money, withdraw from retirement accounts anyway, and flag those withdrawals as early withdrawals

Early withdrawals are marked ⚠ in the Withdrawals column of the evidence's Table. In the real world, early withdrawals from retirement accounts incur a 10% penalty plus income tax. The tool doesn't model the penalty amount, but the flag tells you it would apply.

Once you reach 59.5, all accounts become eligible again and the flag stops appearing.

Stress Test Calculations

Stress tests modify the projection by transforming input data or applying time-based modifiers during the simulation. Some are permanent transforms (applied once before the simulation runs), others are year-based modifiers (applied at specific years during the loop). For the practical guide on what each scenario does, see stress testing your plan.

Market Crash

Type: Year-based modifier

In the crash year, all risky asset balances are multiplied by a drop factor. Cash and high-yield savings are protected.

Crash year: balance = balance × (1 - dropPercent / 100)

In the years after it, growth is slower by a penalty that fades to 0 by the last of the years set. The drop itself is never made back: balances stay below where they would have been.

Growth penalty = -3% × (1 - yearsAfterCrash / slowerGrowthYears)

Defaults: 30% drop in year 2, 5 years of slower growth.

Lower Returns

Type: Permanent transform

Subtracts the specified percentage from every asset's growth rate and the global default rate, floored at 0%:

New rate = max(0, original rate - reduceBy)

Default: reduce by 2%. A 7% default becomes 5%.

Income Loss

Type: Year-based modifier

Starting at the specified year, all income is zeroed out permanently:

if yearOffset ≥ yearsFromNow: income = 0

Default: income stops in year 3.

Spending Spike

Type: Year-based modifier

Starting at the specified year, all expenses are multiplied by a factor permanently:

if yearOffset ≥ yearsFromNow: expenses = expenses × (1 + increasePercent / 100)

Defaults: +50% starting in year 2. $4,000/month expenses become $6,000/month.

High Inflation

Type: Year-based modifier (cumulative: the spike rate is time-limited, the price level it reaches is permanent)

During the inflation window, the engine overrides the base inflation rate. The expense multiplier compounds cumulatively. Each year of elevated inflation builds on the previous years:

inflationMultiplier = ((1 + spikeRate / 100) / (1 + defaultRate / 100))yearsInSpike

Where yearsInSpike is 1 in the first year of the spike, 2 in the second, and so on, up to the spike's length, where it stays once the spike ends. This models the accumulating gap between spike-rate inflation and the default rate that's already baked into per-expense growth.

Example: Default inflation 3%, spike to 8% for 5 years. The annual ratio is 1.08/1.03 = 1.0485:

This multiplier compounds with any spending spike that's also active. After the window ends, inflation returns to the default rate. The multiplier stays at its last value (1.267 in the example), so prices keep the level they reached.

Defaults: 6% inflation for 3 years, starting immediately.

Retire Earlier or Later

Type: Permanent transform

Shifts the retirement date by whole years:

New retirement date = original date + years

Negative values mean earlier retirement. A date that is still ahead never moves to before this month. Income that starts on the retirement date (part-time work, a pension) moves with it. On a suggested date the shift applies after the date is found, so the headline, every model, and the dates the answer suggests move together. This changes when the engine switches from accumulation to withdrawal mode, affecting contributions, surplus deposits, and when withdrawals begin.

Default: 2 years earlier. Range: -20 to +30.

Advanced Analysis Calculations

The standard projection uses fixed growth rates. The advanced analysis modes introduce randomized and historical returns to show the range of possible outcomes. All simulations run in a web worker to keep the UI responsive.

Monte Carlo Simulation

Monte Carlo runs the projection engine hundreds or thousands of times, each with a different randomized return sequence. Only market-rate assets get randomized. Assets with custom growth rates keep their fixed returns.

Return generation: Each month, the engine draws a random return from a drift-corrected lognormal distribution:

  1. Convert annual volatility to monthly: σm = σannual / √12
  2. Compute monthly drift with correction: μm = ln(1 + rannual) / 12 - σm² / 2
  3. Draw a standard normal value z using the Box-Muller transform
  4. Compute the monthly return: return = exp(μm + σm × z) - 1

The -σ²/2 drift correction is critical. Without it, lognormal returns are biased upward, making the simulation systematically optimistic. With the correction, the expected return matches the configured growth rate.

PRNG: Uses Mulberry32, a seedable 32-bit pseudorandom number generator. Every plan runs on the same seed, so simulation i sees the same market whatever the plan: the same plan gets the same count on every device and every load, plans with the same money get the same count, and a costlier plan never scores better by luck. Simulations come in pairs, the second with the first's draws negated, so each month's draws average to zero.

Results: After all runs complete, the engine extracts percentiles (P10, P25, P50, P75, P90) at each year for the Path chart. The card counts the runs where assets never hit $0 before your end year: "money lasts in 462 of 500 simulations", a count of real runs and never a percentage. The best and worst 10% lines read the run at that rank by the month its money runs out, counting runs that last as never.

Configuration: Simulations: 100-5,000 (default 500). Annual volatility: 1-40% (default 15%, matching historical S&P 500). Both live in Assumptions and are saved with the plan. The stress tests you have on apply to every run, so a crash or a spending spike hits each randomized market too.

Historical Backtesting

Backtesting replays your plan against real historical returns. The data source is Robert Shiller's S&P 500 monthly dataset, spanning 1871 to present (~1,850 monthly observations).

Period selection: The engine tests every January-starting period with enough data to cover your full projection length. For a 50-year projection, that means starting years from 1872 through roughly the mid-1970s, about 100+ overlapping periods.

Return application: For each starting period, the engine applies nominal monthly returns (not CPI-adjusted). This is intentional: the projection engine already applies per-expense inflation rates. Using real returns would double-count inflation.

Results: Same percentile extraction as Monte Carlo (P10/P25/P50/P75/P90), and the card counts the start years where the money lasts ("money lasts in 82 of 96 start years"). Additionally identifies the worst-case and best-case starting years by final net worth, which the Path draws dashed and dotted.

Portfolio Survival Heatmap

The heatmap uses a simplified Trinity Study model, separate from the full projection engine. For each combination of withdrawal rate and historical starting year:

Each year: portfolio = portfolio × (1 + annual_return) - inflationAdjustedWithdrawal

Withdrawals are inflation-adjusted with actual CPI, matching the Trinity Study methodology where retirees increase spending to maintain purchasing power. Each withdrawal comes out at year end, after that year’s return. In year n: withdrawal = initialWithdrawal × CPIJan(start+n) / CPIJan(start). The portfolio is 100% stocks (S&P 500 with dividends).

A cell is "survived" if the portfolio stays above $0 for the full duration. The grid tests withdrawal rates from 3.0% to 6.0% in 0.5% steps across all historical starting years. The portfolio is your invested assets ($1,000,000 if none); the retirement length runs from your retirement date (today if already retired, your FI date if there is no retirement date) to your end year, 30 years if the plan has no date.

The simplified model is intentional. The full projection engine accounts for income, expenses, contributions, and drawdown strategy. The heatmap answers a simpler question: "Given just a portfolio and a withdrawal rate, what does history say?"

Saved vs Growth

Read from the monthly projection, from now to the month before retirement (to the plan's end without a retirement date):

In today's money each month's amount is divided by the plan's inflation since the start, amount / (1 + inflation)months / 12, and the balance by the inflation up to its own month, so growth is what the accounts gained above inflation.

Money Flow

The Money flow sums one calendar year of the monthly projection. Each month, its sources pay its sinks, each in order:

Sources: income, then each account drawn, then "Not covered": spending and debt payments that nothing paid for once the money ran out.

Sinks: spending, then debt payments, then savings (contributions and invested unspent income, which go on into each account), then "Not invested": unspent income kept out of the accounts.

A withdrawal that pays for a contribution while you work only moves money between accounts: it drops out of both sides, largest first. Because each month pays its own way, an account never pays into savings. The monthly view divides the year's sums by 12.

The Defaults

All defaults are overridable per entity. These are starting points, not mandates.

Asset Types

Type Default Growth Description
Retirement account7.0%401(k), IRA, 403(b)
Taxable brokerage7.0%Individual/joint accounts
Roth7.0%Roth IRA, Roth 401(k)
HSA7.0%Health Savings Account
High-yield savings4.5%Emergency fund
Real estate equity4.0%Property investments
Other6.0%Custom account
Cash0.0%Liquid cash, checking
Crypto0.0%Bitcoin, Ethereum, etc.

Income Types

Type Default Growth
Salary3.0%
Social Security2.0%
Pension0.0%
Rental income3.0%
Side income0.0%
Other0.0%

Expense Categories

Category Default Inflation
Healthcare5.0%
Insurance4.0%
Housing3.0%
Food3.0%
Transport3.0%
Utilities3.0%
Other3.0%
Fun2.5%

Global Settings

Setting Default Effect
Average return 7.0% Assets using "market rate" grow at this rate
Inflation 3.0% Turns future money into today's money, and each expense line without its own rate grows at it plus its category's offset
Unspent income Auto Account that receives income left after spending, contributions and debt payments: brokerage, then savings, then cash ("Not invested" leaves it out of the plan)
Withdrawal order Taxable first Order of account depletion in retirement
Early withdrawal penalty Off Skip retirement accounts before the penalty-free age
Penalty-free age 59.5 Age when retirement account access is penalty-free (used when the early withdrawal penalty is on)
Monte Carlo 500 simulations, 15% yearly swings How many randomized markets run, and how much their returns swing year to year
Money must last until Age 90 Last year the plan simulates. Without a birth date: retirement + 30 years, else 50 years; never under 30 years

Stress Test Defaults

Scenario Default Values Enabled by Default
Market crash30% drop in year 2, 5 years of slower growthNo
Lower returnsReduce by 2%No
Income lossAll income stops in year 3No
Spending spike+50% in year 2No
High inflation6% for 3 years, starting nowNo
Retire earlier or later2 years earlierNo

Handling Taxes

The tool doesn't model taxes. Tax situations vary by country, state, account type, income level, and personal circumstances. Instead of guessing wrong for most users, we let you adjust.

Workarounds

1. Enter after-tax income. If you earn $100,000 gross but take home $75,000, enter $75,000.

2. Add a "taxes" expense. Create an expense for expected investment taxes, RMDs, or capital gains. Set the inflation rate to 0% or your expected increase.

3. Use conservative growth rates. 7% is pre-tax for taxable accounts. Use 5-6% to approximate capital gains drag.

4. Remember Roth vs. Traditional. A dollar in a Roth account is post-tax. A dollar in a Traditional 401k is pre-tax. The tracker treats them equally in balance terms. You know your marginal rate, we don't.

For anything complex, talk to your accountant.

FAQ


Put it into a plan with your own numbers.