Yet another personal finance calculator / projection to see when to escape from the race. Specific to Singapore.
Decide whether the math is for you alone, or both partners combined. Everything below adapts.
Click any cell to edit directly. Returns are real (after inflation).
Move these. The whole projection responds.
These are capital-access assumptions, not income. At age 55, SA closes (per 2025 SG policy): the balance fills RA up to the set-aside amount above, with any remainder spilling to OA. If RA still falls short, OA tops it up. CPF LIFE payouts are declared separately below and start only at the payout age settings. Once the SRS withdrawal start age is reached, the model drains your SRS balance proportionally each month so it reaches zero by the end of the window (balance ÷ months remaining). The default 10-year window matches the SG penalty-free withdrawal period for the 50% tax exemption.
Enter gross monthly wage per person — the simulator deducts CPF (if auto-contribute is enabled) and effective tax before cash hits the spend account. If self-employed or paid in cash, disable the auto-contribute toggle and enter take-home pay directly.
Income shifts from current to next after the specified months — works equally well for a step down (career change, sabbatical) or a step up (promotion). Set months in current phase very large (e.g., 360) to stay at current income until FIRE. The partner's months working past FIRE keeps them earning past your FIRE date for benefits, gradual exit, etc.
The effective tax rate is a flat approximation of your average rate (total tax ÷ gross income), not your marginal bracket — Singapore IRAS uses progressive brackets, but a single number is usually accurate enough for FIRE-projection purposes. Refer to IRAS for current rates and reliefs; estimate generously if you'd like a buffer.
Money that keeps coming in after FIRE — CPF LIFE annuities (the lifelong tax-exempt payout from age 65) plus an optional schedule of phased income for Barista FIRE, staged drawdowns, or any time-bounded post-FIRE stream.
Phased income runs as an ordered sequence — each phase has a duration in months (minimum 1; non-tail phases with 0 months would be silently skipped), a monthly amount, an optional CPF auto-contribution toggle (for real SG part-time employment), and a per-phase tax rate. The last phase runs forever (its months field is ignored, shown as ∞ and not editable). Use the ↑ / ↓ arrows to reorder non-tail phases. Leave the schedule empty for fully retired with no income.
Reference: BRS ≈ $900/mo · FRS ≈ $1,800/mo · ERS ≈ $2,700/mo (figures shift annually with cohort sums). Use whatever you actually expect, given your planned retirement-sum tier and any top-ups.
CPF LIFE payout is decoupled from RA balance. Re-run the official CPF LIFE Estimator (cpf.gov.sg) if you change FIRE age, retirement-sum top-ups, or enable CPF on a post-FIRE phase — those all affect RA balance, but the payout above is whatever you enter.
Joint household loans (mortgage, car, personal) that drain cash and CPF OA each month for their tenure. Add the loan with its label, start month, and tenure; then expand the row to add per-person cash + OA contributions. In solo mode only the You contribution counts.
Each loan can be split between up to 2 persons — remove and re-add an entry to edit.
One-time inflows and outflows at specific ages — inheritance, downsizing the HDB, a child's wedding, a big medical event. Inflows are positive, outflows are negative. Up to 20 events. The simulation applies them at the right month so the trajectory chart reflects each step.
When the math first turns green — given everything above.
Up to 5 exit ramps. First column auto-tracks the earliest viable FIRE; the last column has an input + Apply for ad-hoc exploration. Click any card to chart its trajectory below. Withdrawal rate is annualised portfolio draw after netting out CPF LIFE and post-FIRE income — <3% conservative, 3–4% safe, 4–5% tight, >5% risky.
Monthly net (income − expenses) at every milestone for the selected scenario · FIRE @ —. Click a scenario card above to retarget. Rows split on income switches, FIRE, partner FIRE-offset, and CPF LIFE start ages.
Pick any age — see the projected balance sheet, active loans, and monthly cashflow at that age under the selected scenario. Inherits the FIRE age from the active scenario card; drag the slider to peek anywhere in your lifetime.
How the projection is computed at each stage of life — words, then math. Read this if a number on screen surprises you; the explanation is usually here.
Everything is in real (after-inflation) dollars and computed month by month from your current age to life expectancy. Annual returns are converted to a monthly rate via geometric compounding: rm = (1 + ra)1/12 − 1. Nominal-flagged rates (CPF, by default) are first converted to real via Fisher: rreal = (1 + rnom) ÷ (1 + i) − 1, where i is the inflation assumption. All dollar inputs (expenses, balances, CPF LIFE payouts, life events) stay flat in today's dollars across time — don't double-adjust for inflation.
Each month the simulator (1) grows every asset class by its monthly real rate, with CPF-aware caps applied during compounding (MA caps at BHS — interest above BHS overflows to SA pre-55 / OA post-55; RA's base interest is frozen post-55 since CPF LIFE payouts are user-supplied and don't depend on RA balance), and credits CPF elevated (extra) interest per the configured age-banded schedule (Singapore default: +1% on the first $60k combined pre-55, +2% on the first $30k and +1% on the next $30k post-55), (2) computes work income, CPF auto-contributions, and tax (if you're still working) — or, post-FIRE, resolves the active phase from your post-FIRE schedule and applies its per-phase CPF toggle and tax rate, (3) adds CPF LIFE / post-FIRE phase income (if applicable for that age), (4) drains SRS on its schedule, (5) deducts expenses and any prorated children cost, (6) applies any one-off life events, then (7) covers any cash shortfall via the configured drawdown waterfall. If the waterfall can't cover the shortfall, the household is flagged as "depleted" at that age.
Each working month, on a gross monthly wage W, the simulator does this in order:
min(W, OWceiling). Total CPF = capped wage × (employee % + employer %), where the rates come from the age-banded rate table. Employee share leaves cash; employer share is added on top into CPF accounts. (Disable per-person if self-employed or paid in cash.)τ, applied to net-of-CPF wage: cash += (W − employee_CPF) × (1 − τ).cash −= expenses + (cost_per_child × n_children) ÷ children_window_months, where the children term applies only inside the children cost window from your current age.If you FIRE before 55, CPF balances continue to compound at their real rates but cannot be tapped for living expenses. The drawdown waterfall taps liquid classes only — by default bonds → CPF OA → equities, with CPF OA gated to age 55+. SRS stays untouched until your configured withdraw-age (default 63). Post-FIRE income flows from your post-FIRE phase schedule (per person): each phase has a duration in months, a monthly amount, an optional CPF auto-contribution flag, and its own tax rate. The last phase runs forever. Set contribute_cpf: true for real SG part-time employment (CPF rates by age band kick in, just like working years); leave it off for freelance / passive payouts and enter the figure as net.
At your 55th birthday, a one-shot transfer fills your RA up to your retirement-sum target R (BRS / FRS / ERS-equivalent — your choice in YAML): SA balance goes in first, then OA tops up any remaining shortfall. SA itself closes (per 2025 SG policy) — any SA balance left over after filling RA spills to OA. From this point on, ongoing CPF contributions continue under the post-55 rates, but the SA bucket no longer accumulates: the SA-allocated portion of each contribution and any MA interest above BHS routes to RA (up to R), then OA. RA's base interest is frozen post-55 (CPF LIFE payouts are user-declared, not derived from RA balance, so we don't compound base growth past 55 to avoid double-counting that as wealth) — but RA still earns the configured elevated bonus on the first $60k combined (Singapore default tier). CPF OA becomes drawable for spending via the waterfall once the set-aside is funded.
From your configured SRS withdrawal age, SRS drains proportionally each month: payout = balance ÷ months_remaining_in_window. Under a window aligned with the simulation, the balance reaches zero by the end of the window. The default 10-year window matches Singapore's penalty-free period for the 50% partial tax exemption (the model does not apply that exemption — it assumes you've controlled timing via the window itself). Payouts land in cash, available for spending.
From the configured CPF LIFE start age, a fixed monthly payout is added to cash for life — tax-exempt. Enter the payout tier (BRS ≈ $900 · FRS ≈ $1,800 · ERS ≈ $2,700, all rough cohort averages) you actually expect, given your projected RA balance at 55 plus any planned top-ups. The model does not derive the payout from your RA balance — it's a user input. Keep it consistent with your retirement-sum target, or you'll be modelling a payout that your RA can't actually deliver.
Each scenario card shows a Capital target alongside Pool at FIRE. The target is a present-value approximation: it sums the PV of remaining lifetime expenses (plus prorated children costs and post-FIRE life events), then subtracts the PV of CPF LIFE and post-FIRE income — all discounted at a single real rate weighted by your at-FIRE allocation across drawable classes (excludes locked MA and RA). It exists as a quick sanity check, not the source of truth: it ignores access gates (SRS age, CPF OA from 55) and allocation drift as you spend down. When the two disagree, trust the simulation — specifically the "Left at" figure on each card.
Cross-cutting mechanics — asset classes, rate handling, drawdown, and what the headline numbers count.
Eight asset classes (cash, bonds, equities, CPF OA / SA / MA / RA, SRS) grow independently at their own real return rate. Equities covers stocks, ETFs, mutual funds, and REITs (treated as one bucket since most retail SG investors track REITs alongside equities). Liabilities are split into a one-shot Others deduction and recurring Loans — see Liabilities & loans below for the full mechanics.
The model computes everything in real (after-inflation) terms internally. Each asset class has a "nom / real" toggle next to its rate input. When set to nom, the entered value is treated as nominal and converted to real on every read using the global inflation field at the top of the balance sheet (Fisher: (1 + nom) ÷ (1 + inf) − 1). The "→ X.XX% real" preview shows the conversion live. Defaults: CPF OA / SA / MA / RA are flagged nominal (matching CPF published rates); cash / bonds / equities / SRS are flagged real (typical planning convention).
The Pool at FIRE figure on each card sums only the drawable classes — cash, bonds, equities, SRS, CPF OA, and CPF SA (pre-55). CPF MA (locked to medical) and CPF RA (paid out via CPF LIFE, which you declare separately) are excluded so the headline reflects money that can actually fund retirement expenses. The trajectory chart line and stacked bands follow the same definition. Your gross balance sheet still shows MA in line items below — it just doesn't roll up into the headline.
SRS is drained on a scheduled per-person basis (Stage 4 above) and does not participate in the waterfall. When household cash still runs negative after expenses and scheduled income, the model draws in the order set under simulation.withdrawal_order in YAML — default bonds → CPF OA → equities, with CPF OA gated to age 55+. CPF SA is never drawn directly and closes at 55 (residual flows to RA up to the set-aside, with the rest spilling to OA). CPF MA and CPF RA are not used for day-to-day retirement spending: MA stays earmarked for medical (capped at BHS, interest above the cap overflows to SA / OA per stage 1), and RA's base interest is frozen post-55 to avoid compounding phantom wealth on top of the user-supplied CPF LIFE payouts. RA still earns the configured elevated bonus interest on the first $60k combined (per the extra_interest schedule), since that's a real cashflow that affects the underlying RA balance — see the CPF LIFE caveat below for how to keep the user-entered payout consistent.
Liabilities split into two kinds. Others is a one-shot per-person debt total deducted from cash at the start of the projection — useful for credit-card balances or short-term debts you don't want to model month by month. Loans are joint household-level recurring outflows (mortgage, car, personal) with a calendar start month, a tenure in months, and a per-person breakdown of cash and CPF OA contributions. Each month inside the active window (start, start + tenure], every breakdown entry drains that person's OA first; any shortfall cascades to cash, matching the SG rule that you must top up cash if OA is insufficient. Loan payments past your FIRE age are also folded into the Capital target as a present-value lump on top of expenses, so the headline "earliest exit" already accounts for them. No interest-rate modelling: the monthly amount you enter is what you actually pay (principal + interest blended, the figure on your bank statement) — the simulator does not recompute it from an interest rate, and outstanding loan principal is not tracked. For a true net-worth figure, subtract your current loan balances manually; for early-payoff or refinancing what-ifs, edit the loan's monthly and tenure directly. Don't double-count: if you've added a mortgage to Loans, do not also enter its outstanding balance into Others — the model already handles the monthly drain, and putting the principal in Others on top of that will deduct it from cash a second time.
Each person has an ordered list of post-FIRE phases — useful for Barista FIRE ("$3k/mo for 5 years, then $0 forever"), staged drawdowns, or modelling a passion project that wraps up at a specific age. Per phase: months (duration), monthly (amount), contribute_cpf (route through CPF auto-contribution at age-banded rates if true — for real SG part-time employment), tax_rate (effective rate applied to that phase only), and an optional label. The last phase ignores its months and runs forever; everything before it is time-bounded. Phases play sequentially from each person's FIRE month (partner phases start after the partner's offset window). The Capital target sums the present-value of phase income, but slightly under-credits CPF-contributing phases since the deposited portion isn't immediately spendable — the simulation path is the truth. To model "fully retired with no income", leave the schedule empty.
Singapore CPF pays an extra interest rate on the first $60,000 of combined balances (RA + OA + SA + MA), with the OA contribution to that combined cap further capped at $20,000. Post-55 the bonus is tiered: extra 2% on the first $30k combined, extra 1% on the next $30k. The model implements this as a configurable extra_interest schedule under cpf in YAML — an array of age-banded entries, each with oa_cap and an ordered list of { rate, cap } tiers. Tiers are applied in order to a single combined balance pool with priority RA → OA (capped) → SA → MA. Set any rate or cap to 0 as the kill-switch if SG policy changes. The model credits each tier's bonus back to the originating account for simplicity — real CPF routes the OA bonus into SA pre-55 / RA post-55, so the OA-spendable share is slightly overstated; if that matters, set oa_cap: 0 to opt OA out of the bonus entirely.
The textarea in the editor drawer is your persistent record and auto-syncs with the controls. Edit it directly and click Apply Edits to load custom values, or use Save in the sticky bar to persist the current state across sessions in your browser only — never uploaded.
Config keys are validated against a strict whitelist. String fields accept only enumerated values. Numeric fields are bound-checked. The parsed object has no prototype, so prototype-pollution payloads can't propagate. All user-supplied values flow through numeric coercion or textContent before display — no innerHTML interpolation of raw input.
Limitations of the model. Read these before betting your career on the green numbers.
This tool runs one deterministic path with constant real returns. It is not a Monte Carlo simulator, does not produce a probability of success, and does not capture sequence-of-returns risk — a market crash in your first 5 retirement years is far more damaging than the average suggests. The 4% rule itself is calibrated to historical worst-case sequences; using a flat-average real return is structurally optimistic. For safety, model at 1% lower equities return, aim for a 25–30% buffer above the capital target, or stress-test by toggling expenses up 20%.
The Withdrawal rate shown on each card is the portfolio's annual draw after CPF LIFE and post-FIRE income are netted out, averaged across the entire retirement window. If you FIRE at 45 with CPF LIFE starting at 65, your actual portfolio draw in years 1–20 is the full expense gap (no CPF LIFE flowing yet) — much higher than the displayed average. Don't compare the displayed rate to the textbook 4% rule directly; that rule is about the year-1 draw on the original pool. A "2.8% withdrawal rate" on the card may be a 4.5% draw in your first decade. For the per-phase picture, read the Cashflow timeline rows.
The model does not derive the CPF LIFE payout from your projected RA balance — you enter the monthly figure directly. Keep it consistent with the tier (BRS / FRS / ERS) implied by your retirement-sum set-aside and any planned top-ups, otherwise you'll be modelling a payout that the RA can't actually fund. For accuracy, cross-check against the CPF Board's CPF LIFE Estimator using your projected RA balance at 65. This decoupling means RA-affecting changes don't auto-update your payout. If you change FIRE age, retirement-sum top-ups, or enable contribute_cpf on a post-FIRE phase (which routes part-time wages into RA at post-55 rates), the modelled RA balance will move but the payout above stays at whatever you typed — re-run the official CPF LIFE Estimator and update the value yourself.
Modelled as a flat monthly cost in today's dollars: (cost_per_child × n_children) ÷ children_window_months, applied each month inside the children cost window from your current age. The model deliberately does not inflate this stream year-by-year — every dollar input in the model is in real (today's) dollars by convention. Real costs are lumpy though — preschool burst, school fees, university spike — so for a known one-off (e.g. $80k tuition at 18, a wedding contribution at 28), use Life events instead of nudging the per-child total upward. That keeps the smooth baseline accurate and lets the lumps hit at the right age.
The OW ceiling, BHS, FRS / ERS, contribution rate table, CPF allocation table, and extra_interest schedule are all user-editable in YAML so you can refresh them each year. The defaults shipped with the tool reflect 2026 figures as of the build date; verify against CPF Board and IRAS if you're modelling a different policy year — and at minimum re-check OW ceiling, BHS, FRS, and the extra-interest tiers each January.
Sequence-of-returns risk; healthcare shocks and direct MA spending (MA accumulates and earns return but is never drawn down for medical costs in the model); home equity if you sell or downgrade your HDB; the SRS 50% partial-exemption rule on withdrawals (control via the withdrawal window instead); estate planning; tax-residency complications if you spend extended periods overseas; any provisions for inheritance tax in jurisdictions you may move to.