A fixed-rate mortgage payment is constant, but the split between interest and principal changes every month. Early payments are mostly interest; later payments are mostly principal. Building the schedule from the standard formula makes that split auditable—useful when comparing lender quotes or checking a refinance break-even.
This note uses the usual U.S. fixed-rate, fully amortizing convention: monthly compounding, payment in arrears, no taxes/insurance in the payment (P&I only).
For principal \(P\), annual note rate \(r_{\text{annual}}\), and term of \(n\) months:
\[ i = \frac{r_{\text{annual}}}{12}, \qquad M = P \cdot \frac{i(1+i)^{n}}{(1+i)^{n} - 1} \]
when \(i > 0\). If \(i = 0\), then \(M = P / n\).
Loan amount $320,000 (e.g. $400,000 price with 20% down), note rate 6.5%, term 30 years (\(n = 360\)).
P <- 320000
r_annual <- 0.065
n <- 360
i <- r_annual / 12
M <- P * i * (1 + i)^n / ((1 + i)^n - 1)
M
## [1] 2022.618
Monthly principal and interest is about $2022.62. Taxes, insurance, and HOA dues (if any) sit on top of this figure in a full PITI payment.
Each month:
balance <- P
rows <- vector("list", 12)
for (k in 1:12) {
interest <- balance * i
principal <- M - interest
balance <- balance - principal
rows[[k]] <- data.frame(
month = k,
payment = round(M, 2),
interest = round(interest, 2),
principal = round(principal, 2),
balance = round(balance, 2)
)
}
schedule <- do.call(rbind, rows)
knitr::kable(schedule, col.names = c(
"Month", "Payment", "Interest", "Principal", "Ending balance"
))
| Month | Payment | Interest | Principal | Ending balance |
|---|---|---|---|---|
| 1 | 2022.62 | 1733.33 | 289.28 | 319710.7 |
| 2 | 2022.62 | 1731.77 | 290.85 | 319419.9 |
| 3 | 2022.62 | 1730.19 | 292.43 | 319127.4 |
| 4 | 2022.62 | 1728.61 | 294.01 | 318833.4 |
| 5 | 2022.62 | 1727.01 | 295.60 | 318537.8 |
| 6 | 2022.62 | 1725.41 | 297.20 | 318240.6 |
| 7 | 2022.62 | 1723.80 | 298.81 | 317941.8 |
| 8 | 2022.62 | 1722.18 | 300.43 | 317641.4 |
| 9 | 2022.62 | 1720.56 | 302.06 | 317339.3 |
| 10 | 2022.62 | 1718.92 | 303.70 | 317035.6 |
| 11 | 2022.62 | 1717.28 | 305.34 | 316730.3 |
| 12 | 2022.62 | 1715.62 | 307.00 | 316423.3 |
Interest in month 1 is much larger than principal. By month 12 the principal share has edged up, but the loan still has decades of amortization left.
# Closed form for total interest over the life of the loan
total_paid <- M * n
total_interest <- total_paid - P
data.frame(
months = n,
monthly_PI = round(M, 2),
total_paid = round(total_paid, 2),
total_interest = round(total_interest, 2)
) |> knitr::kable()
| months | monthly_PI | total_paid | total_interest |
|---|---|---|---|
| 360 | 2022.62 | 728142.4 | 408142.4 |