Rent vs. Buy Calculator

Methodology

What the model actually computes, in the order it computes it. This is the full description of the mechanism — enough to reimplement it, disagree with it, or find a mistake in it.

The one rule

Both households spend the same amount, every month, for the entire horizon. Whoever has the cheaper month invests the difference.

difference = buyer_monthly_cost − renter_monthly_cost difference > 0 → renting is cheaper, renter invests it difference < 0 → owning is cheaper, buyer invests it

Everything else follows from this. Without it you are not comparing two strategies, you are comparing two different amounts of money, and any answer you get is an artifact of that gap rather than of renting versus owning.

Starting position

down = price × down_pct closing = price × closing_pct loan = price − down upfront = down + closing

Both households begin with exactly upfront in cash. The buyer spends it: down becomes home equity, closing is consumed outright. The renter invests the whole amount.

So the buyer starts behind by precisely the closing costs. On the shipped scenario that is $6,500 — and if the buyer sold on day one, their net worth would be negative, because selling costs apply to a home that has not yet appreciated.

Two different rate conventions

This is a detail most calculators get wrong, and it is worth stating because it changes the answer.

A US mortgage note rate is a nominal annual rate divided into twelve equal parts. An investment return quoted as 8.5% a year is an effective annual rate, which compounds. Converting them the same way is incorrect for one of them.

mortgage monthly rate = note_rate / 12 investment monthly rate = (1 + annual_return)^(1/12) − 1

Using rate/12 for the investment would overstate returns: 1.0070833¹² is more than 1.085. Using the compounding form for the mortgage would understate the payment against what a real lender charges. Both conventions are applied where they belong.

The monthly loop

Each month, in this order:

  1. Rent is computed for the current year, plus renters insurance.
  2. Ownership costs are computed against the home value at the start of the month, before this month's appreciation.
  3. The mortgage payment is split into interest and principal, and any extra principal is applied.
  4. Both portfolios grow by one month of investment return.
  5. The cost difference is invested by whoever paid less.
  6. The home appreciates by one month.
  7. Net worth is recorded for both sides.

The ordering matters. Costs are charged against the value at the start of the month, and returns are credited before the new contribution, so a dollar invested this month does not earn a return this month.

The mortgage

payment = loan × r / (1 − (1 + r)^−n) where r = note_rate / 12, n = term_years × 12

Each month, interest is balance × r, and principal is whatever the payment leaves over. Any extra principal is applied on top, capped so the final payment cannot overshoot into a negative balance.

The buyer is charged what actually reached the lender, not the scheduled payment. In every ordinary month these are identical. They differ only in the payoff month, where the remaining balance is smaller than a full principal instalment — there the buyer writes a smaller cheque and keeps the rest. Charging the scheduled figure would overstate their cost and depress their net worth for the whole remaining horizon.

Ownership costs

HOA dues and extra utilities grow at their own fixed rate. They are set by an association budget and by usage, so they never track the home's value.

Property tax, insurance, and maintenance each have a switch. When tracking is on, the cost scales with how far the home has moved from its purchase price:

value_ratio = current_value / purchase_price tracked = base × value_ratio floor = base × (1 + escalator)^year × value_link_floor charged = max(tracked, floor)

The year-one input sets base in each case. For property tax that means your entered annual figure implies an assessed rate of tax_year / price, which is then charged against the current value.

Why the floor exists

With a pure value link and no floor, a deep price decline drives all three costs toward zero. The buyer's carrying cost collapses, they invest the savings, and the model reports that a severe housing crash leaves the buyer better off than steady appreciation. “Buy minus rent” becomes U-shaped in appreciation.

That is an artifact. A home that has lost half its value still needs a roof. At 100%, the floor means a value-linked cost never falls below its own inflation path — appreciation can raise these costs but not cut them. On the upside the floor is inert, so the headline result is unchanged; it binds only on the downside, which is where the unfloored model went wrong.

PMI

threshold = price × pmi_stop_ltv PMI charged while balance > threshold monthly PMI = balance × pmi_rate / 12

The threshold is loan-to-value against the original purchase price, not against current value and not against equity. At 0.80, PMI stops when the balance falls to 80% of price — the same instant you reach 20% equity. Entering 0.20 would model PMI running nearly the whole loan.

A non-zero PMI rate with a zero threshold is rejected as an input error, because it charges PMI for the entire life of the loan and no conventional mortgage behaves that way.

Extra principal

Extra principal is counted as part of the buyer's monthly outlay. Under the equal-outlay rule, that means the renter invests the same amount. Without this the buyer would receive money the renter never gets, and every comparison involving extra payments would be meaningless.

Its effects all fall out of the amortization rather than being modelled separately: the loan retires early, total interest falls, PMI ends sooner because the balance drops faster, and once the loan is gone both the payment and the extra stop — so the buyer's outlay falls sharply and they begin investing the difference instead.

Net worth

renter = portfolio buyer = portfolio + home_value − selling_cost − loan_balance where selling_cost = home_value × selling_pct

The buyer is always scored on what they would actually walk away with if they sold at that moment, selling costs deducted. This is why the buyer starts with negative net worth and why the horizon matters so much.

The crossover

The crossover is the first month the buyer's net worth exceeds the renter's. It is deliberately not called a breakeven: it says nothing about whether buying stays ahead. The model counts how many times the lead changes hands, and reports that count alongside the crossover, so a single date is never mistaken for a durable verdict.

Checks that must pass

The simulation asserts these and refuses to report a result if any fails. A comparison that quietly hands one side extra money is worse than no comparison at all.

  • Principal is conserved. Repaid principal plus remaining balance equals the original loan, at every point — including horizons that end with the loan still open.
  • The loan is gone at scheduled payoff. A fixed-rate loan left alone must amortize to exactly zero on its final scheduled payment.
  • Equal outlay. Both households' lifetime spending must match to within a rounding error. This is the rule the whole comparison rests on, so it is verified rather than assumed.
  • Inputs are finite. NaN and infinity are rejected up front. NaN fails every comparison silently, which previously produced an all-NaN report whose verdict line read “TIE”.

Numerical precision

Monthly amortization is a recursion, and extreme rate and term combinations can accumulate more floating-point error than the result can carry. The model computes an error bound for the given inputs and warns when the reported balance would be materially wrong, rather than presenting a confidently incorrect figure.

What is not modelled

  • Income tax of any kind — no mortgage interest deduction, no SALT deduction.
  • Investment tax. The invested difference grows untaxed.
  • Transaction friction beyond the closing and selling percentages you enter.
  • Rent control, vacancy, or stepwise rent changes. Rent grows smoothly here.
  • Lumpy maintenance. Upkeep is charged evenly; real roofs fail all at once.
  • Liquidity, mobility, and concentration risk. Owning is a large, leveraged, undiversified bet on one asset in one town — often the town your job is in. None of that carries a dollar figure here.

Every rate in the model is nominal. The optional inflation input deflates the final answer into today's dollars for reporting only; it does not enter the simulation, because doing so would double-count.