01Getting started
The whole tool is one page: a form describing a household on top, a results table below. Nothing saves itself — you start from scratch, an example, or a file you load.
The first time you open the page you'll be asked to accept a notice: this is a modeling tool, not advice, it covers federal tax only, and the numbers you enter are sent to whatever server is running the tool to compute your plan. Read it once and check the box to continue.
The header along the top holds every whole-plan control:
| Example | A picker that fills the form with a worked household
— the fastest way to see a real plan before typing your own numbers.
Choosing one replaces whatever is in the form, and picking the same one again
is how you discard your edits and start over. Three are bundled:
|
| Open scenario… | Loads a household you saved earlier, as a
.json file. |
| Save scenario | Downloads the current form as a
.json file, in the same format the command-line
engine reads. |
| Strategy | Picks how withdrawals and conversions are decided — see §7. It starts disabled, because Roth conversion defaults to "I'll specify by period" (§6) and your own schedule drives the plan instead. Switch §6 to "Optimizer decides" and the picker becomes available — though on a server running no optimizer it offers only Naive (§7). |
| Run plan | Sends the household to the engine and renders the ledger at the bottom of the page. |
Every field below is checked by the same engine the command line uses, not by the page itself — a mistake comes back as an error naming the exact person, account, or key at fault, not a generic "invalid input."
02Household
The plan-wide numbers: when it starts, how you file, and how much the household spends before tax.
| Start year | The first calendar year the projection covers. |
| Filing status | singlemfj Married filing jointly adds a second person card in §3. |
| Income target | The gross spending target for the first period, before tax, Medicare and ACA premiums come out — today's dollars. Broken into finer periods in §5 if spending changes over time. |
| Inflation rate | Annual rate used to grow the spending target, account balances and thresholds forward from the start year. |
| ACA benchmark premium | The second-lowest-cost Silver plan premium used to size the subsidy, before retirement age (65) is reached. |
| Healthcare included in target? | If unchecked, an annual healthcare cost field appears — a cost the income target does not already cover. |
03People
One card per person on the plan. A joint filing status adds a second card automatically.
| Birth year | Drives every age-based rule: Medicare, RMD start, Social Security eligibility. |
| Retirement age | The age income from work stops. Two fields appear conditionally based on it — see below. |
| Social Security at FRA | The annual benefit at Full Retirement Age, before any early or delayed claiming adjustment. |
| SS claiming age | When benefits actually start; claiming before FRA reduces the benefit, claiming after increases it. |
| Life expectancy | The age the projection runs to for this person. |
| RMD start age | Leave blank to use the statutory age; only set this to override it. |
Two fields only appear once they're relevant, so the form never asks for a number that would go unused:
- Pre-retirement gross income appears for either of two reasons. If retirement age is past 62, it's needed for the two-year IRMAA look-back into ages 63–64. And if this person is still working when the plan starts, it is their salary for every working year of the plan — whatever their retirement age. That second use is the bigger one: the figure is taxed as ordinary income each of those years, and once the anchor person has retired it counts as cash toward the spending target, which is what funds a plan while one spouse works on. Enter it in today's dollars. It is not indexed, so a plan that opens many years before retirement holds the salary flat and understates what the household would really earn.
- Early-withdrawal election appears when retirement age is under 59½, since a pre-tax withdrawal before then is otherwise a 10% penalty. Choose Rule of 55 (that employer's 401(k) only) or 72(t) SEPP (a fixed annual amount you specify, from a start year you choose) to avoid it.
04Accounts
Every balance as of the plan's start year, one row per account. Ownership is what ties an account to a person's RMD, Rule of 55 and 72(t) rules, so it matters even in a single-filer household.
401(k) / Traditional IRA pretax
Balance, growth rate, owner. Fully taxable on withdrawal; subject to RMDs once the owner reaches the applicable age. Rule of 55 eligible marks the one employer plan that election can apply to.
Roth IRA roth
Balance, growth rate, owner, plus contribution basis and earnings, tracked separately so an early withdrawal is measured against the right ordering rules.
Taxable brokerage brokerage
Balance, growth rate, cost basis, distribution yield and qualified share — the inputs behind long-term capital gain and qualified dividend treatment. Reinvest distributions decides whether yield is paid out as cash or rolled back in, raising cost basis.
Savings / cash savings
Balance and interest rate; optionally marked tax-free for a municipal fund.
Every account type carries a Contribution / yr, which is what lets a plan start before retirement. It is added at the top of each year, and it stops automatically the year that account's owner retires — so in a couple retiring at different times, each person's contributions run to their own retirement, not to the household's first.
One consequence is worth knowing: an account owned Joint is treated as the anchor person's for this purpose, so its contributions stop when the anchor retires even if the other spouse is still working. If a joint brokerage or savings account should keep receiving the still-working spouse's savings, set its owner to that spouse.
The figure is flat and not indexed, and no catch-up contribution is modeled, so a long accumulation phase understates what a real contributor would be putting away in later years.
Use the + (account type) buttons below the table to add a row, and Remove on a row to drop it. A household needs at least one account to fund the spending target from.
05Spending target by period
Up to four periods, bounded by the anchor person's ages, for households whose spending target changes over time — more before Medicare, less after, a lump sum for a wedding, and so on.
Leave a period's target blank and it inherits the period before it — the opposite of the Roth schedule in §6, where a blank period means zero. The first period always takes the household's income target from §2.
06Roth conversion
Two ways to decide how much to convert from pre-tax to Roth each year, and they're mutually exclusive.
| Optimizer decides | The strategy picked in §7 chooses a conversion amount for every year of the plan. Where the server is not running an optimizer this option is named Convert nothing instead, and does exactly that — see §7. |
| I'll specify by period (default) | You type an exact conversion amount for each of the same (up to four) periods as §5, in today's dollars, indexed forward the same way. The strategy picker is disabled — the schedule drives the plan instead. |
In the Roth schedule specifically, a blank period converts nothing . That's the reverse of the spending table in §5, where a blank period carries the previous one forward — worth remembering if a period comes back unexpectedly at $0.
07Choosing a strategy
The strategy decides withdrawal order and conversion size when Roth conversion is left to the optimizer (§6). They all obey the same RMD floor and the same tax rules — they differ in how hard they look for a better plan, and the picker lists whichever of them this server offers. Because §6 defaults to your own schedule, this picker is disabled until you switch it to "Optimizer decides".
Coordinate ascent is CPU-bound and slow, and a small single-core host cannot finish one inside a web request, so many servers do not offer it. If a server offered no optimizer at all, the picker would show only Naive and §6's first option would read Convert nothing — conversions would then be yours to type in §6. Either way nothing is wrong with your household or with the engine: the command line runs every strategy on the same file.
Naive
Conventional withdrawal order, no conversions. The fast, no-surprises baseline — good for a first look, or to see what a conversion strategy is actually buying you.
Bracket-fill default
Converts up to the next bracket or cliff each year — IRMAA tiers, the ACA subsidy edge. Fast — well under a second on a fast machine — and aware of the discontinuities a spreadsheet formula would step right over. The default because it is the optimizer that answers in a reasonable time on an ordinary server.
Coordinate ascent may be hidden
Searches across years for the best after-tax terminal wealth it can find — the best number available, and much the slowest. On the bundled married example: naive about half a second, bracket-fill about 19 seconds, coordinate about three minutes, on a fast machine, and considerably longer on a small server. Because of that it is offered only where the server is configured to allow it, and is missing from the picker otherwise; it is always available from the command line. Choose it when you want the best achievable answer and can wait.
Whichever is selected, the same rule holds everywhere in the engine: an RMD is a floor, never optional, regardless of what the strategy would otherwise choose to withdraw.
08ACA subsidy regime
Only relevant to years before Medicare eligibility, if the household carries marketplace coverage. The regime is set by year, not by plan, because a long plan can outlive a change in the law.
| Cliff | Subsidy eligibility ends entirely at 400% of the Federal Poverty Line — a single dollar over the line forfeits the whole subsidy for the year. |
| Taper | No income ceiling; the premium is instead capped as a share of income, so the subsidy shrinks gradually rather than falling off a cliff. |
Choose One regime for the whole plan, or Changes mid-plan to set the regime from the start year and pick the year(s) it switches.
09Running & reading results
Run plan sends the form to the engine and replaces the results section with a summary and a scrollable, year-by-year ledger.
Summary tiles
| After-tax terminal wealth | What's left, after tax, at the end of the plan — the figure every strategy in §7 is trying to maximize. |
| Lifetime tax and surcharges | Federal tax, NIIT, IRMAA and ACA premium, summed across every year of the plan. |
| Plan span | First year through last year projected. |
| Depletion / shortfall | Shown only if the accounts run out before life expectancy — the year it happens and how many years fall short. |
Today's dollars or future dollars
A pair of buttons above the results switches every figure between two readings of the same plan. Today's $ is the default: each year is discounted back to the plan's start year at your inflation rate, which is the unit every target on the form was typed in, so the gross target reads as the number you entered. Future $ shows the nominal dollars of each year as they would actually be paid. Neither is more correct — today's dollars compare purchasing power across decades, future dollars match what a statement in that year would say.
Reading the table
Four tabs above the results group the columns by question, matching the engine's own grouping so the Excel export never disagrees with what's on screen. Each tab carries a chart above its table, both visible at once:
- Cash and tax — gross target, cash received, wages, Social Security, cash received broken out per account, then what comes back out: federal tax, NIIT, Medicare, IRMAA, ACA premium, any early-withdrawal penalty, and finally net spendable, shortfall and Roth conversion. Charted as stacked bars of cash by source with the gross target stroked across them.
- Income detail — ordinary income, long-term gains, qualified dividends, taxable Social Security and interest, as stacked bars of taxable income by kind.
- MAGI and subsidy — the IRMAA, ACA and NIIT definitions of income, each different, plus provisional income and the ACA subsidy itself.
- Balances — total and per-account balance at year end.
Hovering a chart gives that year's figures as a readout, which is usually faster than finding the row.
The one distinction worth holding onto: Cash is the gross target requested that year; Net is what's actually left to spend once tax, Medicare and ACA premiums come out. The gross number alone always overstates what the household can spend.
A banner above the column names marks the runs that are a breakdown of another column rather than extra money on top of it. Wages, Social Security and the per-account columns add up to Cash received — they are not additional to it — and the six tax and premium columns add up to Total obligations. Columns under no banner are nobody's component: the gross target is a request, the shortfall is a gap, and a Roth conversion never reaches your pocket at all.
10Save, load, export
- Save scenario writes the household to a
.jsonfile you can hand to a colleague, keep as a baseline, or re-open later with Open scenario…. It's the same file formatengine.cli planreads on the command line. - Download to Excel appears above the results table once a plan has run, and exports the exact ledger you're looking at, workbook-ready.
A saved scenario is the same format the command-line engine reads, including
the per-period spending and Roth conversion tables in §5/§6 —
python -m engine.cli plan household.json runs on
anything this form can save.
11What it won't do
- Federal tax only. No state income tax is modeled.
- Not advice. It's a projection built from the numbers you type and the growth and inflation assumptions you choose — nothing here verifies those assumptions will hold for the next several decades, because nothing can.
- One household at a time. There's no portfolio of scenarios to compare side by side inside the page — save each one out if you want to keep several.
- Salaries and contributions are flat. Pre-retirement income and each account's yearly contribution are held at the figure you type for every working year, with no raises, no indexing and no catch-up contributions. A plan that opens a year or two before retirement is barely affected; one that opens decades early understates both earnings and savings, and the further out it starts the more it understates them.
- Working years are not a spending model. Before the anchor person retires there is no income target to meet, so the table books the whole salary as cash received and taxes it. Those rows' cash and net columns are not a claim about what the household spends or saves — only the tax and the balances mean anything until the plan reaches retirement.
- Charts are on screen only. Each results tab has one, but the Excel export is figures without pictures — the table stays the artefact the export matches. Chart whatever you need in your own tool from the exported rows.
- Filing status never changes mid-plan. A couple whose plan runs past one spouse's life expectancy keeps being projected as a joint return for the remaining years. A real surviving spouse normally files as single, which taxes the same income more heavily — so those years show less tax than they should, and the ending wealth is optimistic. The results panel says so whenever a plan has years like these. It is often the single largest thing this tool is too kind about, so treat a long survivor stretch as a figure to check with a professional rather than one to rely on.
Verify anything you intend to act on with a qualified financial advisor or tax professional.