0
0%
$0
$0
$0
$0
—ⓘ
—
—
Input Distributions
Per-year distribution of sampled returns and inflation across all paths. Band = p10–p90 · solid = median · dashed = min/max.
Saved Scenarios
Change Log
For more details, consult the README.md.
- 11.129d Annual Details now shows Roth conversions as the IRA withdrawals they are, and conversions draw from the larger IRA. A Roth conversion is money leaving the IRA, so the IRA WD, IRA1- and IRA2- columns now include it. Before, a year could show a large conversion with little or no IRA withdrawal, which looked wrong even though the balances were correct. RMD stays in its own columns (it is the involuntary draw and is never a conversion). The Federal and State tax columns now include the tax on conversions, so they add up to Total Tax and the Taxation chart shows the real tax. Conversions are now taken from the larger IRA first (spilling to the smaller only when the larger cannot supply the full amount) instead of being split by size, which is what you would actually do and avoids converting a token slice out of a tiny IRA. This changes each IRA's balance over time and therefore each person's future RMDs; the combined yearly tax is unchanged. Clicking a year to open the Tax Payment Planner now sends the correct per-IRA voluntary, conversion, and tax figures.
- 11.1287 Maximize Conversions now actually maximizes: available Cash can cover conversion taxes. Previously nothing in the tool paid a conversion's tax bill from outside funds, so a $20,000 Extra Annual Roth Conversion only landed about $13,700 in Roth - the rest went to the tax on its own withdrawal. Standard practice is to cover that tax from Cash so the full amount gets to grow tax-free, and Maximize Conversions now does exactly that, on top of its original behavior of routing leftover IRA withdrawals into Roth. It uses only the Cash you have: when Cash is short it funds what it can, and at $0 Cash nothing changes, so existing plans are unaffected until you turn it on. Turn on nerd knobs to control the two behaviors separately ("Convert Excess to Roth" and "Use Cash"), in which case the Optimizer also sweeps each strategy both with and without cash-funded taxes (💵 rows).
- 11.1287 Optimize Spend and Optimize Conversions moved to the Optimizer tab, and Optimize Conversions is now on by default. Both only ever affected the Optimizer, but sat in the sidebar next to the strategy settings that drive every tab, which made them look like plan settings. They now live at the top of the Optimizer tab under "Search options", where they apply. Optimize Conversions starts on so the conversion-optimized ⇌ rows are found without having to know to ask for them; turn it off if you want a faster sweep. Note that ⇌ rows only appear where an extra conversion actually improves the result for one of the top-ranked strategies, so a plan whose best strategies do not benefit from converting more will correctly show none. Your saved scenarios and shared links keep working unchanged.
- 11.1287 Smaller fixes. The Roth Conv column in Annual Details had silently lost its explanatory tooltip to a naming typo (as had the Roth Growth column); Roth Conv's now spells out why it can read lower than the amount you asked to convert. The Break Even explainer is a compact ⓘ next to the year instead of a standing button, and it no longer makes you click before telling you anything - hover reads the reason, click pins it open, click again closes it.
- 11.1271 Three fixes from testing the Extra Conversion field and Break Even. (1) The Optimizer's conversion-amount search could recommend a Guyton-Klinger conversion so large that GK could only "afford" it by continuously cutting your future spend behind the scenes -- the search now rejects any amount that isn't actually sustainable for GK, the same stability check already used elsewhere in the optimizer. (2) The "Extra Annual Roth Conversion $" tooltip now says plainly that it is capped only by the remaining IRA balance, not by your IRA Goal -- a conversion moves money IRA-to-Roth rather than out of the household, so it is allowed to draw the IRA below that goal on purpose. (3) When Break Even shows “—”, a new ⓘ next to the stat identifies the specific conversion year that erases an otherwise-sustained lead, instead of leaving you to guess why.
- 11.1253 Optimizer strategies loaded from the table now actually match what the table showed. Clicking a "⇌ Optimize Conversions" row to load it previously dropped the extra conversion amount that made that row special, so the loaded plan's Break Even (and everything else) could disagree with the Optimizer table. A new "Extra Annual Roth Conversion $" field now holds that amount, is filled in automatically when you load a ⇌ row, and is shareable/saveable like any other input. Loading a cyclic-brokerage or IRMAA/ACA-ceiling ⇌ row now also correctly carries those settings over. Also clarified the Conv Savings tooltip: it only counts tax actually paid so far, so it can look good even when Break Even (which also counts the tax still owed on money left in the IRA) says the conversions never really paid off.
- 11.1247 Optimizer: Break Even now shown for Optimize Conversions strategies. When the Optimize Conversions checkbox is on, the top 5 strategy rows now report a Break Even year (same permanent-crossover definition as the single-scenario stat) in a new column, and a new "Earliest Break Even" objective (nerd mode) ranks strategies by how soon their conversions permanently pull ahead. Strategies that never sustain a lead show “—”.
- 11.1240 Break Even now requires the lead to hold for the rest of the plan. A rare scenario could report Break Even off a single year where the converting (or excess-withdrawal) plan brushed even before falling behind again, sometimes for good. Break Even is now the earliest year the plan pulls ahead and stays ahead through the end of the simulation, showing “—” if that lead is never sustained. Same fix applies to excessOC. See “What is Break Even?” below.
- 11.11ff Refactor: No behavior changes. If the page looks stale after this update, do a hard refresh.
- 11.11f3 Internal cleanup: source files renamed to a shorter, consistent scheme (optimizer_core.js, optimizer_ui.js, optimizer_tests.js, optimizer_text.js, optimizer_styles_responsive.css). The simulation engine and the page UI now live in separate files. No behavior changes. If the page looks broken after this update, do a hard refresh (Ctrl+Shift+R) to clear the old cached files.
- 11.11dc Break Even and Opp. Cost are now measured with a true no-conversion re-simulation. The tool re-runs your whole plan with the Roth conversions removed and compares after-tax wealth year by year. The no-conversion plan keeps the money in the IRA and pays its own larger RMD taxes and IRMAA surcharges later, so the benefit of avoiding those is now fully counted. The old approximation could report a Break Even year when there were no conversions at all, and could fail to report one for conversions that clearly paid off. Break Even now appears only when conversions actually happen. The same rework applies to the excess-withdrawal opportunity cost (excessOC). See "What is Break Even?" below.
- 11.11c8 Improved bar charts. Hover over or click legends to isolate that value. Double click to restore. Line legends are unchanged. IRMAA is now presumed to occur in years 1 and 2 (matching the future value) - a bug caused it to only show up on year 2.
Stress is now performed automatically when Historical Monte Carlo is selected and applies to the current strategy. Line charts now also have the "isolate" behavior in addition to the "click to dismiss, click to reshow."
Cycle Brokerage will now fill up the 0% or 15% tax bracket (whichever falls below any current limits). Previously it was only pulling enough to meet spending.
Other minor UI improvements also made. - 11.11ae Income & Expenses chart: added a note that shown incomes are after-tax (pre-tax figures are in Annual Details).
- 11.11ad Added Spending to Annual Details to focus on spending.
- 11.1133 Architectural improvements, no features changed.
- 11.1125 IRMAA now respects Medicare age.
- Age-65 gate, per spouse. The IRMAA surcharge is charged only for spouses who are 65+ (actually on Medicare) — a couple aged 61/59 no longer pays IRMAA no matter how large a Roth conversion is. With one spouse 65+ and one younger, only the older spouse's half is charged.
- Tier display fix. The IRMAA Tier column (and chart milestone) previously appeared one year before the surcharge was actually charged; both now use the same 2-year MAGI lookback as the dollar amount, and show -none- before age 65.
- IRMAA Ceil strategies unlocked pre-63. Before any spouse is 63 (the earliest year income can affect a premium, given the 2-year lookback), the IRMAA-tier conversion ceiling relaxes to the top of the federal bracket containing it — no more pointlessly capped conversions in your early 60s. Same for “Lesser of IRMAA or Bracket.”
- Medicare Parts B+D base cost now shown on charts and table for spouses 65+ — illustration only, not deducted from spendable.
- Distinct chart colors. IRMAA is now deep pink and Medicare teal on all charts (they previously shared nearly identical pinks); the IRMAA milestone marker matches the pink.
- 11.1119 State retirement-income taxes are now much more accurate. 16 states (Alabama, Colorado, Connecticut, Georgia, Illinois, Iowa, Kentucky, Maine, Maryland, Michigan, Mississippi, New York, Ohio, Pennsylvania, Virginia, Wisconsin) now apply their real pension/IRA exemptions, caps, and credits instead of taxing all retirement income as ordinary income. Several states have limitations; limitations are listed below the state once it's selected. See, e.g., CA, MA, NC, SC, NE, AZ, and MT.
- 11.1102 State retirement-income exemptions (Illinois & Pennsylvania): IRA/401k/pension distributions are no longer taxed by states that exempt them. Illinois and Pennsylvania now correctly exempt these withdrawals (interest, dividends, and capital gains remain state-taxed). Other states are unchanged.
- 11.10ee Pension start age, optimizer symbol legend, and a Guyton-Klinger fix:
- Pension start age. Model a pension that begins after you retire (e.g. retire at 60 while the pension starts at 65). Leave the start age at 0 to begin at retirement.
- Optimizer symbol legend. A new legend explains the symbols shown on strategy names (✓ ✦ ▼ 🗘 🔄 ⇌ ⚠️ 🟢 🚨 ⚓).
- Guyton-Klinger sustainable-spend fix. When no strategy can fund your spend goal, the suggested fallback spend no longer reports a Guyton-Klinger value that only “works” by cutting spending every year — and the suggested strategy is now clickable to load.
- 11.10cf Numerous user experience improvements: IRA Draw strategies now tested to 20%, After-Tax-Spend searches higher spend rates and a suggested value is offered. Other changes include tooltip clarity improvements, chart improvements, and showing Charts first by default.
- 11.10a2 Added additional charts for clarity: Taxation, Income vs Net Income, Inflows vs Outflows, Earnings vs W/D.
- 11.1099 Baseline strategy is now ranked by total economic value, not terminal wealth alone. The pinned ⚓ baseline is the best no-conversion strategy. Guyton-Klinger Optimize Spend no longer reports an unsustainable spend. Optimize Spend now applies a stability floor and accepts a higher initial spend only if the guardrails never cut real delivered spending below one guard band of the initial.
- 11.1091 >Fixed a
NaNin a Monte Carlo.
Fixed a shortfall. Fill strategies will exceed the threshold when needed to meet the spend goal.
However, the ACA Cliff ceiling is now its own strict strategy: it never breaches the cap. If spending can’t be met under the target the plan is flagged untenable (⚠️ in the Optimizer) rather than silently overspending.
- 11.1060 Stress mode now ranks worst decades by real inflation-adjusted Compound Annual Growth Rate (Real CAGR): real CAGR = (1 + equity) / (1 + inflation) − 1. High-inflation decades like the 1960s–70s stagflation, and the Lost Decade (1999-2010) correctly rank as worse for retirees than a pure equity crash with near-zero inflation. Depression-era crashes also had high deflation which is now clamped to a minimum of -1% (rather than -9%).
- 11.1042 Guyton-Klinger Guardrails withdrawal strategy:
- Dynamic spending rules. The Guyton-Klinger strategy adjusts annual spending based on portfolio withdrawal rate. It skips inflation adjustments when the prior year return was negative, and cuts spending 10% when the withdrawal rate exceeds the upper guardrail; raises spending 10% when withdrawal rate falls below the lower guardrail. Supports higher initial withdrawal rates (~5–5.5%) by absorbing sequence-of-returns risk through spending flexibility.
- Four configurable parameters: Upper/lower guardrail (default ±20% of IWR) and cut/raise percent (default 10%). Annual Details Income category shows gkSpend and gkAdj columns.
- 11.1001 Best "Baseline" is used for strategy comparison:
- Honest baseline. The optimizer now also runs every strategy family with no Roth conversions and no cyclic brokerage maneuvering, no QCDs, and pins the strongest of those as a ⚓ BASELINE reference row at the top of the results. Every other strategy is measured against it — because "strategy A beats strategy B" only means something relative to the best you can do without conversion/brokerage tricks.
Older changes…
- 11.1048 Shorter share URLs: (up to 70% shorter); older/longer URLs should still load unchanged.
- 11.1019 Cyclic-brokerage drawdown fixed:
- 11.1018 Δ columns honor Future/Current $; tax tooltips clarified:
- Cleaner table. Infeasible (bracket-unreachable) rows are hidden by default — click the Infeasible legend to reveal or hide them. Failed plans always sort below successful ones. Every column header now has an explanatory tooltip.
- 11.fed Charitable Giving (QCDs) & UX Improvements:
- Qualified Charitable Distributions (QCDs): New Charitable Giving (QCD) section in the sidebar. Enter an annual household QCD maximum — the simulation transfers that amount directly from the larger eligible IRA to charity each year (age 70½+ per person). QCDs satisfy the RMD requirement without adding to taxable income, reducing IRMAA exposure. Two modes: Always donates the full amount every eligible year; As Needed applies only enough to drop two IRMAA tiers (or escape the surcharge entirely, whichever requires fewer dollars). The per-person limit is $111,000 for 2026 (CPI-indexed annually per SECURE 2.0). QCDs appear as a gray bar in the Income & Expenses chart.
- Dollar display toggle: The Future $ / Current $ toggle has moved to the left of the tab bar (always visible). Future $ shows nominal amounts as they will actually appear; Current $ restates everything in today's purchasing power for easy year-to-year comparison.
- Strategy panel switches: Maximize Conversions (formerly "Max Conversion"), Cycle Brokerage (formerly "Cyclic"), Optimize Spend, and Optimize Conversions (formerly "Conv Optimizer") are now all in the strategy sidebar with labels to the right of each switch. Toggle labels are positioned so that the green (on) position visually aligns with the label.
- 11.ecc Withdrawal Rate: Corrected Portfolio Withdrawal percent calculations. Added netOutflow, grossOutflow and inFlow columns for summary information.
- 11.ecb Withdrawal Timing: Each simulation year now auto-selects Early (January) or Late (December) withdrawal timing. Conversion years use Early — maximizing Roth compounding duration. Spending-only years use Late — the full portfolio compounds before the withdrawal exits, gaining D×r per year (~$3,500/yr on a $50k draw at 7%). No manual toggle; the algorithm tracks prior-year conversion activity. A new Timing column in Annual Details shows Early(Conv) or Late(Spend) for each year.
- 11.eca Bear-Start Overlay (Historical Monte Carlo): In Historical mode, the bottom 25% of paths begin with a randomly-sampled worst-decade historical sequence before continuing with random draws. The likelihood of a "Bear start" market is 23%, so this adds realistic sequence of return risks (SORR).
- 11.ec9 Stress Mode: Monte Carlo "Stress (worst sequences)" runs the worst historical retirement-start sequences scored by first-decade real (inflation-adjusted) CAGR. Shows sequence-of-returns risk directly — each line is a real historical scenario. Chart labels show nominal equity CAGR, inflation CAGR, and real CAGR for each scenario. Clicking on a legend hides all other plots. Will your retirement withdrawal strategy survive the stagflation of the 1960s–70s? The tech bubble of 2000? This will tell you.
- 11.ec8 State Bracket Inflation Fix: MT, ND, AL, OH, and SC have statutory fixed income tax brackets (they were being incorrectly inflated which would understate future state taxation). Other states are unaffected. Known limitation: the standard deduction for AL, OH, and MT is fixed by statute but is being adjusted - future fix to be provided.
- 11.ec7 State Tax Expansion: Added AL, AZ, CO, IN, KY, MA, ME, MN, MT, ND, OH, SC, WI to the state income tax dropdown. All states adjusted to latest available information.
- 11.ec6 Cycle Brokerage: New Cycle Brokerage toggle in the strategy box enables alternating IRA draw years and brokerage LTCG harvest years. IRA-draw years and brokerage harvest years alternate. The ratio of IRA to brokerage cycles is based on the ratio of the account balances. E.g. if the brokerage is 1/3 the size of the IRA total, the cycle will be 1 year brokerage, 2 years IRA draws. As the asset balances change, the ratio may also change. In Brokerage harvest years spending is funded from brokerage gains at capital-gains rates (often 0–15%). Excess brokerage funds are reinvested (DRIP) so dividends stay inside brokerage and don't leak to Cash as ordinary income. Two orderings are supported: IRA-first (🗘, red) harvests after N IRA years; Brokerage-first (🔄) harvests at the start of each cycle. The Optimizer and Monte Carlo always run all three variants (baseline + IRA-first + Brokerage-first) and surface the best. The subCycle column in Annual Details shows IRA/Brok/⚠Brok per year. One benefit of Cycle Brokerage is earlier reduction of brokerage assets that would otherwise grow increasing later capital gains.
- 11.e64 BETR (Break-Even Tax Rate): Annual Details now shows the break-even future tax rate for each year's Roth conversion. Avg BETR summary stat shows the average across all conversion years. "Conv Optimizer" determines whether conversions realize any tax savings and are indicated with (⇌) Bug fix: eliminated shortfalls in cases invoving brokerage withdrawals.
- 11.e52 URL compression: all share URLs now use short parameter names (57% shorter). Share button opens a copyable popup panel on all tools matching Income Tax Planner style. Income Tax Planner gets an "Open in Tax Planner →" button that pre-fills Retirement Tax Planner with state, SS income, and capital gains. Backward compatible — existing long-key bookmarks still load.
- 11.e4f User Experience polish throughout. Roth conversion & opportunity cost tracking calculates when conversions or cash withdrawals "pay off". Break Even at the top says when that year is. New Opp. Cost category and columns added to Annual Details. Future IRA Tax % marginal rate when IRA is eventually distributed; auto defaults the last simulation year marginal rate. Choose your heirs total tax rate.
- 11.e4a Fixed start age bug (table now starts at retirement year on URL load). Updated withdrawal strategy descriptions in How To. Added color legend to Annual Details table.
- 11.e1a New (nerd) feature: view input distributions in Monte Carlo.
- 11.df0 Monte Carlo uses historical inflation 1928–2024 and growth (based on S&P), that historical inflation also is used to escalate the spend-goal rather than using a fixed rate. Stats display CAGR (Compound Annual Growth Rate) instead of arithmetic median - e.g. the CAGR growth rate is the "true" rate where the median rate is the "middle" rate over the entire period. Example: -20% growth for 3 years, 10% growth for one year, then +20% growth for 3 years the CAGR is about -0.38%, but the median is 10%. CAGR gives you the real net growth.
- 11.dd9 Monte Carlo uses Historical data from real S&P 500, bond, and international returns (1970–2024). Account Composition shows Est.Rtn advisory column (median before inflation); Monte Carlo shows per-asset-class return ranges (Eq/Bonds/Intl).
- 11.dd6 Added ordered withdrawal strategy (CBIR/RIBC/BIRC). Fixed error where Spend Goal was inflated prematurely.Defaults bracket strategy changed to `Below IRMAA`. Fill provides feedback: ✓ or ⚠ status with max feasible spend estimate; clicking ⚠ sets After-Tax Spend to the bracket maximum and triggers recalculation.
- 11.dad Ages (current age and RMD start age, live-updating) added; optimizer always runs with Max Conversion on (it was almost always better); Strategy defaults were changed; other defaults changed, too.
- 11.da6 Bug fixes: survivor SS benefit was ~2× correct (delayed credits were accruing past claiming age — fixed); dividends now correctly compound inside IRA and Roth accounts (previously only Brokerage received the dividend growth component). New feature: Retirement Start Age — enter the age you plan to retire; the simulation inflates brackets, SS COLA, and spend goal forward to that year automatically. Start age defaults to your current real-world age (birth-month aware). You may have retired already, but this tool starts where you are. Monte Carlo: click any result row to load that strategy. Annual Details: Roth1/Roth2 per-person balance columns now available under Roth Δ. Minor Version numbering changed: lowercase hex((day-of-year × 24) + hour).
- 11 Account composition (equity/bond ratio + intl equity %) per account in Assumptions; Spouse Roth account now fully simulated — withdrawals split proportionally, conversions routed IRA→Roth per person; Balances chart Both/Mine/Spouse toggle; Optimizer and Monte Carlo skip rebuild when inputs are unchanged.
- 10 Shorthand dollar inputs (1.2M, 48k); Include Spouse toggle replacing birthyear=0 hack; ACA FPL cliffs in bracket dropdown; collapsible sidebar sections; assets section reorganized with Roth2/CashReserve placeholders; IRMAA tier ceilings and dynamic MFJ/SGL bracket dropdown recovered from stranded branch.
- 8 Added "Proportional Withdraw %" strategy with configurable IRA withdrawal boost (0–200% above spend goal); optimizer tests it at 0/5/10/20/50%; Roth Conv bar now stacks on top of taxes in the lower chart; optimizer table highlights best row per column (lowest tax, lowest tax rate, highest spend, highest wealth).
- 7g The tax rate on capital gains is now proportional to the basis. Pension is now included in the total so over withdrawal was prevented. Cash gains were not included (interest and dividends) in the initial withdrawal, but were added at the end - above and beyond what was actually needed. The mass of columns have been tamed with live selectable options, including suppressing columns that have only zeros, grouping by association.
- 7f Fixed HTML cautions. Fixed error in calculating what to do with surplus. It was putting some surplus into Roth even though no IRA withdrawals had occurred. CapitalGains calculation was wrong, and the tax burden for Brokerage withdrawals was also incorrect.
- 7e Fixed more bugs, added much more information (See the README.md). And added a new standalone tool.
- 7d Updated taxation calculations to use a more thorough calculator.
- 7c Save/load functionality fixed. Adjust IRMAA calculations to account for different growth rate of the tax from the CPI rate. IRMAA is tied to Medicare which annually increases by 5.6% over the last 20 years.
- 7b More state rates. Fixed most calculations. Minor UI changes.
- 7a Now has various state rates. Fixed most calculations.
- 6v Implemented Save/Load/Export/Delete Scenarios.
- 6u Implemented SS Fail. More UI fixes. Moved all strategy items to the top.
- 6t Solved a math issue causing NaN to occur. Cleaned up the visuals.
- 6s Fancy highlighting of the tables. Fixed broken strategy changer. Tests moved into separate file.
- 6r Moved the heavy text (top drawers) into a separate file.
- 6q Beautifications and hover notes. More self tests with an indicator on screen if they fail. Started the Social Security "meltdown" implementation. Added (empty) Insights tab.
- 6p Corrected instructions for Single filer usage. Fixed error in brokerage tracking. Added brokerage dividend rate. Dividends automatically accrue to Cash.
- 6n Calculation fixes.
- 6m More self tests, some rework.
- 6k Reworked tax brackets for sanity ease of update. Added more instructions.
- 6j Move style sheet out for readability.
- 6i Remove the Recalculate and Optimize buttons. Use the similarly named tabs as the buttons.
- 5hp Integrated Federal SS "Tax Torpedo" logic, California HSA add-backs, and IRMAA cliff surcharges.
- 5h Added change log and instructions.
- 4g Do rate limit lookups based on inflation. Add suggested values.
- 4f Use cpi% to adjust taxation (brackets).
- 4e Use calculated birthyear for correct RMDs.
How to Use
- Withdrawal Strategy: The Withdrawal Strategy box (top of sidebar) controls how the simulation draws from your accounts each year. Set the After-Tax Spend goal (annual after-tax income needed) and Spend Delta (yearly change — default −1% per historical data). The IRA Goal field (just below the strategy box) sets a floor in today's dollars, inflation-adjusted (CPI) to each year so it tracks the inflation-indexed brackets, IRMAA tiers, and ACA cliffs it is meant to manage: most strategies draw from the IRA only until it reaches this (inflating) balance, then shift to other sources. For Reduce IRA in N Years it is the amortization target; for all other strategies it is the minimum balance the optimizer will not draw below.
Detailed Strategy Discussion…
Common to all strategies: QCDs (if configured) are applied first — they satisfy the RMD requirement dollar-for-dollar without adding to taxable income. Any remaining RMD obligation after QCDs is then taken as a taxable IRA withdrawal. Both happen before strategy logic runs.
Proportional Withdraw +% — draws IRA, Brokerage, and Cash proportionally (relative to their balances) to cover the spend goal. An optional IRA-only boost adds boost% × spend goal on top of that; the after-tax surplus flows to Roth conversion. At 0% boost this is the pure proportional baseline. Gap fill if still short: Brokerage + Cash (60/40), then Roth as last resort.
Reduce IRA in N Years — calculates the annual IRA draw needed to amortize the IRA down to the IRA Goal (today's dollars, inflation-adjusted to each year) over the remaining simulation years (similar to a mortgage payment). RMDs count toward that target; the strategy draws any remaining amount beyond RMDs. Gap fill if the IRA draw alone doesn't cover spending: Cash → Brokerage → Roth.
Fill Federal Tax Bracket / IRMAA Tier (soft ceiling) — draws IRA up to a chosen ceiling (top of a federal bracket or an IRMAA tier threshold), then fills any remaining spending from non-taxable sources in order: Cash → Brokerage → Roth. The ceiling is soft: if spending still can’t be met after those are exhausted and the IRA has funds, the simulation draws extra IRA above the ceiling to fund mandatory spending — because spending is a hard requirement and the alternative (an unfunded shortfall while a large IRA sits idle) is worse. The amount drawn above the ceiling appears in the
ForcedIRAcolumn with that year’sBracketOverage; the consequence is extra tax (or, for IRMAA, a Medicare surcharge). The ceiling also defines the room available for Roth conversions.ACA Cliff (strict ceiling) — draws IRA only up to a chosen multiple of the Federal Poverty Level, then fills spending from Cash → Brokerage → Roth. Unlike the bracket/IRMAA ceilings, the ACA cap is strict: it is never breached, because exceeding it forfeits the entire ACA premium subsidy (a cliff, not a gradual cost). If spending can’t be met within the cap, the plan is genuinely untenable at that spend level — the shortfall is shown (red rows) and the strategy is flagged ⚠️ in the Optimizer, rather than silently overspending the cap. Note that on a large pre-tax IRA, required minimum distributions alone can push income above a low FPL multiple, making ACA targeting infeasible regardless of withdrawals.
IRA Draw % — withdraws a fixed percentage of the current IRA balance each year regardless of the spend goal (RMDs count toward the target). Gap fill if the after-tax IRA draw falls short of spending: Cash → Brokerage → Roth. Useful for a mechanical, balance-proportional drawdown pace.
Ordered (CBIR / RIBC / BIRC) — draws from accounts in a strict sequence until the spend goal is met; unlike other strategies, all spending is handled in this ordered pass (nothing is pre-withdrawn).
- CBIR (Cash → Brokerage → IRA → Roth): depletes taxable accounts first, letting tax-advantaged balances compound longest. The conventional "textbook" depletion order.
- RIBC (Roth → IRA → Brokerage → Cash): burns tax-free Roth first; useful for stress-testing Roth-heavy portfolios or modeling an intentional Roth-first drawdown.
- BIRC (Brokerage → IRA → Roth → Cash): clears brokerage before tax-deferred; useful when brokerage gains are low and IRA deferral is still valuable.
Cycle Brokerage — a toggle that layers on top of any strategy. When enabled, the simulation alternates between IRA draw years and brokerage harvest years. The cycle length N is recomputed each year as round(IRA ÷ Brokerage), so the ratio self-corrects as balances evolve. In a harvest year, spending is funded from brokerage capital gains instead of IRA withdrawals, realizing gains at the preferential LTCG rate (often 0% for many retirees) rather than as ordinary income. Advantages: (1) steps up the cost basis each cycle, reducing future LTCG tax; (2) frees the full IRA bracket headroom for Roth conversions in harvest years; (3) lower MAGI in IRA years can keep IRMAA tiers lower. DRIP (dividend reinvestment) is automatically forced on so dividends reinvest into brokerage rather than leaking to Cash as ordinary income. Two orderings are available: IRA-first (🗘 red) runs N IRA years then harvests — better when the brokerage has high unrealized gains (delay harvest to let IRA deplete first); Brokerage-first (🔄) harvests immediately at the start of each cycle — better when brokerage basis is high (low gains) so the tax cost of harvesting is small. The Optimizer and Monte Carlo always evaluate all three variants. Caveats: harvest years raise MAGI, triggering IRMAA surcharges 2 years later and potentially causing ACA cliff loss; with a very high-gains brokerage the strategy can become less effective as effective LTCG rate rises over time.
Strategy panel controls — these sit with your strategy in the sidebar and affect every tab:
- Maximize Conversions — gets as much into Roth as the plan allows, two ways at once. First, any IRA withdrawal surplus beyond the spend goal is converted to Roth rather than left in Cash. That is a same-dollar move: the money was already withdrawn and taxed on its way out, so this only changes where it lands, and nothing is lost to tax by doing it. Second, it uses available Cash to cover conversion taxes rather than letting those taxes come out of the conversion itself — the standard advice for Roth conversions, and what makes an Extra Annual Roth Conversion $ of $20,000 actually deliver $20,000 to the Roth instead of roughly $13,700 (see the field below). It only ever uses Cash you have: when Cash is short it covers what it can, and at $0 Cash it changes nothing. Nerd knobs split this into its two halves, Convert Excess to Roth and Use Cash, so you can run either alone. On by default in the Optimizer (see note below); toggle it on in single-scenario mode to match.
- Extra Annual Roth Conversion $ — a fixed dollar amount converted from IRA to Roth every year, on top of whatever your strategy and Maximize Conversions already do. Two things to know. (1) The amount you enter is the gross withdrawal from the IRA, and a conversion owes tax on it. Without Use Cash, that tax comes out of the conversion, so less arrives in Roth than you typed — $20,000 entered lands about $13,700 at a 31% marginal rate. With Use Cash on, Cash covers the tax and the full $20,000 lands. Either way, the Roth Conv column in Annual Details shows what actually arrived; the extraConv column (Opp. Cost category) shows the gross. (2) It is capped only by your remaining IRA balance each year — it does not stop at your IRA Goal, because a conversion moves money IRA-to-Roth rather than out of the household, and drawing the IRA down is usually the point. This is the same amount the Optimizer's Optimize Conversions search solves for, and loading a ⇌ row fills it in for you.
- Cycle Brokerage — layers cyclic IRA/brokerage alternation on top of any strategy (see Cycle Brokerage above).
Optimizer search options — these two live at the top of the Optimizer tab rather than the sidebar, because they change only what the Optimizer searches for and have no effect on your single-scenario plan, the charts, or Monte Carlo:
- Optimize Spend — after the Optimizer finds successful strategies, it binary-searches each one for the highest sustainable spend goal that still ends with at least two years of funded wealth. Those rows are marked ✦.
- Optimize Conversions — for the top five Optimizer strategies, sweeps additional fixed annual conversion amounts ($25k steps) to find the best Extra Annual Roth Conversion $ for each, and adds a ⇌ row per winner. Click one to load that whole plan, including the conversion amount, back into the sidebar. Slower (5–15 sec for large IRAs).
Charitable Giving (QCDs) — the Charitable Giving (QCD) block at the bottom of the Annual Income & QCDs section lets you enter a combined household annual QCD maximum. A Qualified Charitable Distribution is a direct transfer from a traditional IRA to a qualifying charity. It satisfies the RMD requirement for that year without adding to your taxable income, which can reduce or eliminate IRMAA Medicare surcharges. Rules: age 70½+ per person (the simulation uses birth month for precision); the IRS limit is $111,000/person/year in 2026, CPI-indexed annually. QCDs are sourced first from the larger eligible IRA, then the smaller. Two modes: Always (switch right, green) donates the full amount every eligible year regardless of tax situation — useful for regular charitable giving goals. As Needed (switch left) applies only as much as needed to drop two IRMAA tiers from your projected MAGI, or to escape the surcharge entirely — whichever requires fewer dollars. Use this when your primary goal is IRMAA avoidance rather than a fixed giving commitment. In either mode your entered amount is the ceiling — the simulation never exceeds it.
Optimizer note: Every Optimizer row converts surplus after spending to Roth, regardless of your sidebar setting — enable Maximize Conversions in the strategy panel to match that assumption in single-scenario mode. Cash-funded conversion taxes work differently: normally Optimizer rows just follow your sidebar setting, so toggling Maximize Conversions changes what the table reports. Under nerd knobs the Optimizer instead sweeps it as its own dimension, listing each strategy both with cash-funded taxes (💵) and without, so you can see what that choice is worth rather than assuming it. Those extra rows only appear when you actually have Cash, since the feature does nothing without it.
- What is “Break Even”? When your plan does Roth conversions, the tool quietly runs your entire plan a second time with the conversions removed: the money stays in the traditional IRA, no conversion tax is paid, and that bigger IRA later forces bigger Required Minimum Distributions, taxed in whatever bracket you are actually in those years (including the higher Single rates a surviving spouse pays, and any Medicare IRMAA surcharges the RMDs trigger). Each year the two plans are compared on equal footing, and the earliest year the converting plan pulls ahead and stays ahead for the rest of the plan is marked as Break Even. A year where the converting plan is only briefly ahead before falling behind again does not count. It only appears if conversions actually happen, and shows “—” if the lead never becomes permanent. When it does show “—”, a ⓘ appears next to it; click that to pinpoint exactly which conversion year is the one that erases the lead for good, and how far the plan got before that.
Both plans are compared by after-tax portfolio value: taxable (IRA) assets are reduced by the tax that will eventually be owed on them, and non-taxable (Roth) assets count at face value. The net figure is shown as Total Wealth on the main chart. The IRA discount rate is either each plan's own current tax rate, or the Marginal Heirs Tax if you entered one (see 4. Assumptions). Conversions pay tax early, so the no-conversion plan usually leads at first; the crossover often lands when RMDs ramp up, or when one spouse passes away and the survivor’s tax rate jumps when filing Single, aka “the widow penalty”.
The year-by-year numbers are in Annual Details → Opp. Cost (the convOC column; excessOC is the same comparison for surplus IRA withdrawals banked to Cash, using the same permanent-crossover definition of Break Even). One caveat: with Guyton-Klinger guardrails the no-conversion plan may adjust spending on different years, since the guardrails react to that plan's own portfolio. That is the honest comparison, not an error.
- 1. Profile & Ages: Enter the birth year and month of each person and estimated life expectancy. The current age, RMD start age, and projected first-year RMD amount are shown below each person's birth fields and update live. Use the Include Spouse checkbox to model a single taxpayer — unchecking it hides all spouse fields and excludes the spouse from the simulation. Retirement Start Age is the age at which you stop earning income; the simulation inflates tax brackets, SS COLA, and spending forward to that year automatically.
- 2. Assets at Retirement Age: Enter balances in today's dollars. Brokerage Basis is used to calculate capital gains vs. principal. Total all after-tax investment assets into Brokerage, and all cash-like holdings into Cash. The Reinvest Brokerage Dividends checkbox keeps dividends inside the brokerage account (growing both balance and basis); when unchecked, dividends flow to Cash. Should one spouse predecease the other, all IRA assets are inherited by the remaining spouse. Enter Roth balances separately — Your Roth IRA and Spouse Roth IRA are tracked independently throughout the simulation. The collapsible Account Composition subsection records Equity/Bond ratios — informational only in single-scenario mode, but used by Monte Carlo Bootstrap and Stress modes to apply per-account return sequences.
- 3. Annual Income & QCDs: Input annual Social Security and pension amounts. Set the start ages to see the impact of delaying benefits — the Pension Start Age lets you model a deferred pension that begins after retirement (leave 0 to start at retirement). SS amounts are adjusted annually by the CPI/COLA rate. Survivorship is the percentage of the pension that continues after You pass away. Enable Pension has COLA only if your pension includes a cost-of-living adjustment — most pensions are fixed-dollar. The Charitable Giving (QCD) block at the bottom of this section handles Qualified Charitable Distributions.
- 4. Assumptions: Dividend Rate and State Taxation are the most-changed inputs — set these first. Social Security Fail models the projected trust fund shortfall year and reduced payout.
Growth rate — nominal, not real. Enter the nominal (before-inflation) annual return for IRA, Roth, and Brokerage. The tool deducts inflation internally — do not pre-subtract inflation yourself. The real (purchasing-power) growth rate is approximatelynominal − inflation(Fisher equation:(1+g)/(1+i)−1precisely). For reference: the S&P 500 has returned roughly 10% nominal (≈7% real) since 1928; a diversified 60/40 portfolio averages 7–9% nominal; a conservative bond-heavy allocation 4–6%. Note that the dividend rate is additive — 5% growth + 1.5% dividends = 6.5% total. Asset balances and RMDs grow at the nominal rate, which is why nominal is the correct input even though real growth is what you feel in purchasing power.
Seeing real (inflation-adjusted) values. All dollar amounts in Annual Details are shown in future nominal dollars by default. Use the Future $ / Current $ toggle in the tab bar (left of Annual Details / Charts / Optimizer / Monte Carlo) to restate every balance and income figure in today's purchasing power — this is the clearest way to judge whether your plan preserves your standard of living over time.
Cash Interest is for HYSA and money-market holdings. Inflation drives spending-goal escalation; CPI/COLA drives bracket indexing and SS cost-of-living adjustments (they often differ). Medicare/IRMAA dollar amounts grow at CPI + Inflation combined. - After Changes... Changes to any input — balances, rates, ages, strategy switches, or any other value — trigger an immediate recalculation. On the Annual Details table, rows are highlighted yellow when filing status changes to Single; pink/red means the portfolio cannot cover the required draw (a real shortfall — for the strict ACA Cliff strategy this means the plan is untenable at that spend). For the soft Fill Bracket / IRMAA strategies, the
ForcedIRAandBracketOveragecolumns show where spending was funded by drawing IRA above the ceiling. The Balances chart has a Both / Mine / Spouse toggle. The Optimizer sweeps all strategy variations and highlights the best result per column. The Monte Carlo tab runs all variations against stochastic return sequences and reports survival rates. Both tabs skip a full rebuild if inputs are unchanged. Use Import/Export to save, load, or delete named scenarios.
For limitations and features not currently modeled, see the README.md.
Where is the Code
You can run this locally (download the *.html and *.js and *.css files from GitHub): github.com/nightskyguy/retirement_assets. Charts require loading remotely: cdn.jsdelivr.net/npm/chart.js.
You can directly run the code from GitHub: tools.netcitizen.us/retirement_optimizer.html
Page loads are tracked anonymously using Google Analytics and Cloudflare Web Analytics. No personally identifiable information is collected; no account data you enter is ever sent anywhere — it stays entirely in your browser.