Inspectable Arithmetic for the TFSA vs RRSP vs FHSA Calculator (Canada)

Version 1.1
Last verified: May 2026

Transparent arithmetic is the operating system of this calculator.

This document publishes the formulae, computational structure, and assumptions used to generate the outputs displayed on the calculator page.

No opinions. No hidden assumptions. Just arithmetic.

Purpose

This calculator compares the after-tax future value of contributing a fixed cash amount to different Canadian registered accounts: TFSA, RRSP, and FHSA. It models recurring or lump-sum contributions, simple net investment growth, and explicit tax treatment on contribution and withdrawal under marginal tax rates you set or that are estimated from your inputs.

Definitions

Let:

Core Equations

1. Net return and monthly rate

Net annual nominal return (after fees):

rnet = (r − f) / 100

Nominal monthly rate:

rm = (1 + rnet)1/12 − 1

If “Show results in real dollars” is enabled, the calculator converts to a real annual rate first:

rreal = \(\dfrac{1 + r_{\text{net}}}{1 + i_d}\) − 1

and then to a real monthly rate:

rm,real = (1 + rreal)1/12 − 1

This is the same pipeline summarized on the calculator’s real-dollars mode: first the annual real return in decimal form, \((1+r_{\text{net}})/(1+i_d)-1\) — equivalently \((1+r_{\text{net}})/(1+i/100)-1\) when \(i\) is your inflation input as a percent — then that annual rate is converted to a monthly rate with the 12th-root step above.

The engine uses a single monthly rate for all accounts. There is no asset-location modeling (no different returns per account).

2. Contributions and horizon

Time horizon in months:

N = 12T

Contribution schedule:

3. Refund arithmetic

For any RRSP or FHSA deposit d in a month, the modeled refund is:

refund = d × tnow/100

Refund handling modes:

There is one refund bucket per strategy. The calculator does not separately label which portion of Brefund originated from RRSP vs FHSA contributions.

4. Monthly evolution (per strategy)

For each month t = 0,…,N−1, the engine:

  1. If t ∈ {12, 24, …} (first month of simulation years 2, 3, …), increases remaining TFSA and RRSP room per the TFSA/RRSP multi-year rules above, before allocating that month’s contribution.
  2. Computes the intended gross contribution Gt for that month based on mode (monthly, annual/12, or lump at t = 0).
  3. Allocates Gt between TFSA, RRSP, and FHSA according to the strategy and room constraints (TFSA/RRSP remaining room, plus FHSA rules in the next section).
  4. Applies refunds on RRSP/FHSA deposits into the refund bucket when “reinvest refund” is selected.
  5. Applies growth to all balances using the monthly rate.

Growth step (using either rm or rm,real):

BTFSA,t+1 = BTFSA,t(1 + rm)
BRRSP,t+1 = BRRSP,t(1 + rm)
BFHSA,t+1 = BFHSA,t(1 + rm)
Brefund,t+1 = Brefund,t(1 + rm)

TFSA and RRSP contribution room (multi-year)

The calculator takes opening TFSA contribution room and RRSP deduction room (totals available “today,” including unused carry-forward from prior years). Each deposit reduces the corresponding remaining room. No top-up is applied in month 0: your opening inputs are treated as the starting caps for simulation year 1.

At the beginning of simulation years 2, 3, … (i.e. at months 12, 24, …, before that month’s contribution is allocated), the model adds:

Unused room carries forward inside the simulation: whatever remains after contributions in a year is still available next year, plus the January top-ups above. Eventually, if contributions are large enough for long enough, carry-forward can be fully used and only the recurring annual top-ups remain—then further savings spill to non-registered once both registered rooms for that month are exhausted. This is a simplified calendar (one January refresh per simulation year, monthly contributions); it does not model CRA posting lags, pension adjustments, or employer plans.

FHSA Room and Allocation Rules

5. FHSA annual room and lifetime contribution cap

Let:

For each simulation year y = 1,…,⌈T⌉, FHSA room at the start of the year is:

room1 = R0
roomy = R   for y ≥ 2

At each month, any amount assigned to FHSA reduces roomy for that calendar year. Independently, cumulative contributions cannot exceed the lifetime cap:

CFHSA,tot,t ≤ L

The dollar amount that may be deposited to the FHSA in a month is therefore capped by both the remaining annual roomy and the remaining lifetime headroom (L − CFHSA,tot before that month’s deposit). Investment growth inside the FHSA increases the account balance but does not increase CFHSA,tot and does not count toward L.

When a strategy allocates to FHSA first, the engine:

  1. Contributes up to the minimum of remaining annual room, remaining lifetime room, and that month’s gross allocation.
  2. Spills any remainder of that month’s contribution to TFSA or RRSP, depending on the strategy.

Unused FHSA contribution carry-forward (year to year) is not modeled; only the annual room series above and the lifetime cap L are enforced. Verify current limits at canada.ca.

6. Strategies

Each strategy is a fixed priority order for filling TFSA, RRSP, and (when eligible) FHSA from each month’s gross contribution. Account room and the FHSA lifetime cap are enforced at each step; any amount that cannot be placed in those three buckets goes to non-registered (last).

If FHSA is not eligible, the engine runs two strategies only:

If FHSA is eligible, the engine runs all six permutations of the three registered accounts (non-registered always last):

The headline optimal result is whichever of the simulated strategies (two or six, depending on FHSA eligibility) maximizes total after-tax value at the horizon. The UI ranks every simulated strategy from highest to lowest after-tax total.

Withdrawals and After-Tax Values

7. Withdrawal tax treatment at horizon

At the end of the horizon (month N), balances are:

BTFSA,N, BRRSP,N, BFHSA,N, Brefund,N

After-tax values by account:

VTFSA = BTFSA,N
VRRSP = BRRSP,N(1 − tret/100)
\(\displaystyle V_{\text{FHSA}} = \begin{cases} B_{\text{FHSA},N} & \text{if FHSA is eligible and “plan to buy using FHSA” is checked (home-qualified)} \\ B_{\text{FHSA},N}(1 - t_{\text{ret}}/100) & \text{otherwise (FHSA behaves like RRSP)} \end{cases} \)
Vrefund = Brefund,N

Total after-tax value for a given strategy is:

V_{\text{total}} = V_{\text{TFSA}} + V_{\text{RRSP}} + V_{\text{FHSA}} + V_{\text{refund}}

Allocation Summary

The calculator reports a human-readable “optimal split” sentence based on the simulated strategy that maximizes Vtotal:

Worked Example (Using Your Last Inputs)

The example below substitutes the last inputs you used on the calculator page (if available from this browser). Values are rounded for readability.

Open the TFSA vs RRSP vs FHSA calculator, enter your assumptions, and then click “Inspect the Arithmetic” to see a worked example here with your values.

Assumptions and Limitations

  1. All simulations use monthly time steps with deterministic compounding and fixed contribution schedules.
  2. TFSA and RRSP room use opening user-entered balances plus January top-ups from simulation year 2 onward (new TFSA dollars and 18%-of-income RRSP room capped by a modeled dollar limit); unused room carries forward until used.
  3. Investment returns, fees, and (optionally) inflation are modeled as constant over the full horizon.
  4. RRSP and FHSA refunds are either treated as immediately spent (default) or reinvested in a TFSA-like bucket; actual tax timing and withholding are more complex in practice.
  5. Tax rates tnow and tret are either estimated from modeled employment income and province using the same tax engine as the Canada Personal Income Tax Calculator, or set directly via manual override; they are held constant over the horizon.
  6. FHSA modeling enforces the annual room you specify (default $8,000) and a $40,000 lifetime contribution cap per person; growth inside the FHSA does not count toward that cap. Contribution carry-forward and detailed withdrawal conditions beyond the home-qualified toggle are not modeled.
  7. Non-registered (taxable) accounts are not included in this version; it is an account-to-account comparison between registered options.
  8. All results are rounded for display; internal calculations use full floating-point precision.

If any discrepancy is identified between this documentation and the calculator output, the arithmetic in the engine governs.

What This Calculator Does Not Include

Sources and References