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 (default: 50 years), the engine executes these steps in order:
- Apply stress test modifiers for the current year (market crash multiplier, growth rate adjustments)
- Grow asset balances by their monthly growth rate
- Accrue interest on liabilities
- Calculate income with annual growth applied
- Calculate expenses with per-category inflation applied
- Apply stress test multipliers to income and expenses (zeroing income, spiking expenses, inflation overrides)
- Make debt payments
- Handle contributions or withdrawals depending on accumulation vs. retirement phase
- Apply one-time events scheduled for this month
- Record the snapshot (balances, totals, deltas, cumulative values)
This produces a time series of monthly snapshots. The chart and tables are rendered 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:
- Starting balance: $100,000
- Growth rate: 7% annually
- Monthly rate: 7% / 12 = 0.583%
- After 1 month: $100,000 × 1.00583 = $100,583
- Growth this month: $583
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:
- Loan balance: $20,000
- Interest rate: 6% annually
- Monthly payment: $400
First month:
- Interest: $20,000 × (6 / 100 / 12) = $100
- Balance after interest: $20,100
- Balance after payment: $19,700
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:
- Salary: $80,000/year
- Growth rate: 3%
- Year 5: $80,000 × 1.035 = $92,742/year
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 designated a surplus asset with the "deposit surplus" option enabled, the extra money is deposited into that account each month. This models automatically investing leftover cash.
If surplus is negative: the engine assumes untracked income covers the gap (spouse's income, side gigs, etc.). It doesn't force a balanced budget.
Surplus asset selection: You choose which asset receives surplus deposits. If no surplus asset is set, 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. If you only care about investment growth, skip them entirely. The projection still works—it just won't model surplus deposits or retirement withdrawal needs.
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 specifies a target asset, it's applied there. Otherwise, it falls back to the surplus asset. If neither exists, the event has no effect on balances.
Examples:
- $50,000 inheritance in June 2028 → deposited into your brokerage
- -$30,000 wedding in September 2027 → withdrawn from your savings
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
Tax-efficient (default): Assets are sorted by priority:
- Taxable accounts (brokerage, savings, cash) — priority 1
- Traditional retirement (401k, IRA, HSA) — priority 2
- Roth accounts (Roth IRA, Roth 401k) — priority 3
- Everything else — 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 tax-efficient, 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:
- Calculate your current age from birth date
- If age < 59.5, exclude retirement account types (retirement, roth, hsa) from eligible assets
- Withdraw from remaining accounts normally
- If all non-retirement accounts are depleted and you still need money, withdraw from retirement accounts anyway—but flag those withdrawals as early withdrawals
Early withdrawal flags appear in the projection's Withdrawals tab. 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)
During the recovery period, an additional growth rate penalty is applied, ramping from -3% back to 0% over the recovery duration:
Recovery penalty = -3% × (1 - yearsIntoRecovery / recoveryYears)
Defaults: 30% drop in year 2, 5-year recovery.
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.
Expense 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 (time-limited, cumulative)
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. 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:
- Year 1: 1.04851 = 1.049 → expenses 4.9% above baseline
- Year 3: 1.04853 = 1.153 → expenses 15.3% above baseline
- Year 5: 1.04855 = 1.267 → expenses 26.7% above baseline
This multiplier compounds with any expense spike that's also active. After the window ends, inflation returns to normal.
Defaults: 6% inflation for 3 years, starting immediately.
Retire Earlier or Later
Type: Permanent transform
Shifts the retirement date by the specified number of years:
New retirement date = original date + years
Negative values mean earlier retirement. This changes when the engine switches from accumulation to withdrawal mode, affecting contributions, surplus deposits, and when withdrawals begin.
Default: 0 years (no change). 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:
- Convert annual volatility to monthly:
σm = σannual / √12 - Compute monthly drift with correction:
μm = ln(1 + rannual) / 12 - σm² / 2 - Draw a standard normal value z using the Box-Muller transform
- 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. The seed defaults to the current timestamp, but can be fixed for reproducible results in testing.
Results: After all runs complete, the engine sorts final portfolio values and extracts percentiles (P10, P25, P50, P75, P90) at each year. The success rate is the percentage of runs where the portfolio survived without depleting.
Configuration: Simulations: 100–5,000 (step 100). Annual volatility: 1–40% (default 15%, matching historical S&P 500). Stress tests are not applied during Monte Carlo—the randomized returns replace deterministic scenarios.
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 1871 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). Additionally identifies the worst-case and best-case starting years by final portfolio value.
Portfolio Survival Heatmap
The heatmap uses a simplified Trinity Study model—not 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: the initial withdrawal amount grows at 3% per year, matching the Trinity Study methodology where retirees increase spending to maintain purchasing power. In year n: withdrawal = initialWithdrawal × 1.03n.
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. Default portfolio size is $1,000,000 over 30 years.
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?"
Contributions vs Growth
Extracted from the monthly projection snapshots. For each year, the engine sums two cumulative totals:
- Contributions: total monthly contributions + total surplus deposits
- Growth: total investment returns (compound growth)
The crossover point is the first year where cumulative growth exceeds cumulative contributions (and contributions are positive). After this point, the market has made you more money than you've invested—compound interest is doing the heavy lifting.
Sankey Cash Flow
The Sankey diagram extracts flows from a single monthly snapshot. Flows differ by phase:
Accumulation: Income sources → expenses (by category) + debt payments (by liability) + asset contributions (by asset) + surplus deposits. Income is distributed proportionally across destinations based on configured amounts.
Retirement: Asset withdrawals (by asset) + remaining income → expenses (by category) + debt payments (by liability).
If tracked income doesn't cover all outflows, the diagram adds an "Untracked Income" source to balance. Only flows greater than zero are included. The annual toggle multiplies all monthly flows by 12.
Milestones
Formula:
Progress = Net Worth / FIRE Target × 100
Four milestone thresholds:
- 25%—Foundation: Compound interest starts to visibly matter.
- 50%—Halfway: The second half often goes faster thanks to compounding.
- 75%—Coast: Even without more contributions, you might reach FI eventually.
- 90%—Final Stretch: Close enough to start planning the transition.
Progress is recalculated whenever balances or the FIRE target change. Milestones are tracked in the projection summary and shown on the chart.
The Defaults
All defaults are overridable per entity. These are starting points, not mandates.
Asset Types
| Type | Default Growth | Description |
|---|---|---|
| Retirement Accounts | 7.0% | 401(k), IRA, 403(b) |
| Taxable Brokerage | 7.0% | Individual/joint accounts |
| Roth Accounts | 7.0% | Roth IRA, Roth 401(k) |
| HSA | 7.0% | Health Savings Account |
| High-Yield Savings | 4.5% | Emergency fund, cash |
| Real Estate Equity | 4.0% | Property investments |
| Other | 6.0% | Custom account |
| Cash / Checking | 0.0% | Liquid cash |
| Cryptocurrency | 0.0% | Bitcoin, Ethereum, etc. |
Income Types
| Type | Default Growth |
|---|---|
| Salary | 3.0% |
| Social Security | 2.0% |
| Pension | 0.0% |
| Rental Income | 3.0% |
| Side Income | 0.0% |
| Other | 0.0% |
Expense Categories
| Category | Default Inflation |
|---|---|
| Healthcare | 5.0% |
| Insurance | 4.0% |
| Housing | 3.0% |
| Food & Groceries | 3.0% |
| Transportation | 3.0% |
| Utilities | 3.0% |
| Other | 3.0% |
| Discretionary | 2.5% |
Global Settings
| Setting | Default | Effect |
|---|---|---|
| Default Growth Rate | 7.0% | Assets using "market rate" grow at this rate |
| Default Inflation Rate | 3.0% | Base inflation for expense calculations |
| Track Income | On | Include income in cash flow calculations |
| Track Expenses | On | Include expenses in cash flow calculations |
| Deposit Surplus | Off | Route positive surplus to designated asset |
| Surplus Asset | None | Which asset receives surplus deposits |
| Drawdown Strategy | Tax-efficient | Order of account depletion in retirement |
| Respect 59.5 Rule | On | Skip retirement accounts before penalty-free age |
| Penalty-Free Age | 59.5 | Age when retirement account access is penalty-free |
| Projection Years | 50 | How far into the future to simulate |
Stress Test Defaults
| Scenario | Default Values | Enabled by Default |
|---|---|---|
| Market Crash | 30% drop in year 2, 5-year recovery | No |
| Lower Returns | Reduce by 2% | No |
| Income Loss | All income stops in year 3 | No |
| Expense Spike | +50% in year 2 | No |
| High Inflation | 6% for 3 years, starting now | No |
| Retire Earlier/Later | 0 years | No |
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
How accurate are these projections?
As accurate as your inputs. Markets don't follow averages year-to-year. The projections show what would happen if growth rates stayed constant—useful for comparing scenarios and planning, not for predicting exact future values.
Why doesn't the tool model taxes?
Tax situations vary too much by jurisdiction, account type, and personal circumstances. Instead of making assumptions that would be wrong for most users, we let you adjust your inputs to reflect after-tax values.
Is 7% growth realistic?
7% is approximately the historical real (inflation-adjusted) return for US stocks over multi-decade periods. Your results will vary. Use 5-6% if you're more conservative or expect different market conditions.
Why does healthcare inflate at 5%?
US healthcare costs have historically outpaced general inflation by roughly 2 percentage points. The 5% default reflects this trend. Adjust it if your situation differs or you're outside the US.
What happens if my assets run out?
Balances stop at $0. This is a signal to adjust your plan—increase savings, reduce expenses, delay retirement, or revisit your assumptions. Use the stress tests to find out how close to the edge you are.
Why are stress test scenarios permanent? Can I model a temporary job loss?
Most stress tests model structural changes (lower long-term returns, permanent income loss) because those are the scenarios that break plans. High inflation is the exception—it has a configurable duration. For temporary job loss, use the income loss scenario to check worst-case, then turn it off. The tool models extreme scenarios for safety margins, not average cases.
Is my data private?
Yes. Everything stays in your browser's localStorage. Nothing is sent to any server. Your financial data never leaves your device.
→ Open the Fire Planner
→ Mathematical Foundations: full derivations and proofs
→ Practical guide: setting up and using the tracker
→ The 4% rule explained