Debt Snowball Calculator: Pay Off Debt Faster
The Debt Snowball Method is a popular debt reduction strategy where you pay off debts in order of smallest balance to largest balance, regardless of the interest rate. This method focuses on psychological wins to keep you motivated and build momentum.
How the Debt Snowball Method Works:
List Your Debts: Gather all your debts (credit cards, personal loans, student loans, etc.) and list them from the smallest outstanding balance to the largest.
Pay Minimums: Make the minimum required payment on all your debts, except for the smallest one.
Attack the Smallest Debt: Throw any extra money you have available each month at the debt with the smallest balance.
Roll the Snowball: Once the smallest debt is completely paid off, take the money you were paying on it (its minimum payment + any extra money you were applying) and add it to the minimum payment of the next smallest debt.
Repeat: Continue this process, "snowballing" your payments from one debt to the next, until all your debts are paid off.
While mathematically the Debt Avalanche method (paying highest interest first) can save you more money in interest, the Debt Snowball method is highly effective for those who need quick wins and motivation to stay on track with their debt payoff journey. The psychological boost from eliminating smaller debts can be a powerful motivator to stick with your plan.
How to Use This Calculator:
Enter details for each of your debts, including its current balance, annual interest rate, and minimum monthly payment. Then, specify any additional amount you can commit to paying towards your debts each month. The calculator will simulate the debt snowball method and show you how quickly you can become debt-free, along with a detailed payoff schedule.
Debt Snowball Payoff Calculator
Extra Monthly Payment (e.g., 100):
Add Another Debt
Remove Last Debt
Calculate Snowball Payoff
Your Debt Snowball Plan:
Total Payoff Time:
Total Interest Paid:
Total Amount Paid:
Detailed Payoff Schedule:
Month
Total Payment
Interest Accrued
Principal Paid
Debts Paid Off
Remaining Balances
var debtCount = 0;
function addDebtField() {
debtCount++;
var container = document.getElementById("debtInputsContainer");
var debtDiv = document.createElement("div");
debtDiv.id = "debt_" + debtCount;
debtDiv.style.border = "1px solid #ccc";
debtDiv.style.borderRadius = "4px";
debtDiv.style.padding = "15px";
debtDiv.style.marginBottom = "15px";
debtDiv.style.backgroundColor = "#fff";
debtDiv.innerHTML = `
Debt #${debtCount}
Debt Name (e.g., Credit Card A):
Current Balance (e.g., 5000):
Annual Interest Rate % (e.g., 18):
Minimum Monthly Payment (e.g., 100):
`;
container.appendChild(debtDiv);
}
function removeDebtField() {
if (debtCount > 0) {
var container = document.getElementById("debtInputsContainer");
var lastDebtDiv = document.getElementById("debt_" + debtCount);
if (lastDebtDiv) {
container.removeChild(lastDebtDiv);
debtCount–;
}
}
}
addDebtField();
addDebtField();
addDebtField();
function calculateSnowball() {
var extraPayment = parseFloat(document.getElementById("extraPayment").value);
if (isNaN(extraPayment) || extraPayment < 0) {
alert("Please enter a valid positive number for Extra Monthly Payment.");
return;
}
var debts = [];
for (var i = 1; i <= debtCount; i++) {
var nameInput = document.getElementById("debtName_" + i);
var balanceInput = document.getElementById("debtBalance_" + i);
var rateInput = document.getElementById("debtRate_" + i);
var minPaymentInput = document.getElementById("debtMinPayment_" + i);
if (!nameInput || !balanceInput || !rateInput || !minPaymentInput) {
continue; // Skip if debt fields were removed or not fully rendered
}
var name = nameInput.value;
var balance = parseFloat(balanceInput.value);
var rate = parseFloat(rateInput.value);
var minPayment = parseFloat(minPaymentInput.value);
if (isNaN(balance) || balance < 0 || isNaN(rate) || rate < 0 || isNaN(minPayment) || minPayment 0; }) && totalMonths < maxMonths) {
totalMonths++;
var monthInterestAccrued = 0;
var monthPrincipalPaid = 0;
var monthTotalPayment = 0;
var debtsPaidThisMonth = [];
var currentMonthDebtDetails = [];
var snowballTargetIndex = -1;
for (var i = 0; i 0) {
snowballTargetIndex = i;
break;
}
}
for (var i = 0; i < activeDebts.length; i++) {
var debt = activeDebts[i];
if (debt.balance <= 0) {
continue;
}
var interestThisMonth = debt.balance * (debt.rate / 100 / 12);
monthInterestAccrued += interestThisMonth;
totalInterestAccruedOverall += interestThisMonth;
var paymentTowardsThisDebt = debt.minPayment;
if (i === snowballTargetIndex) {
paymentTowardsThisDebt += currentSnowballAmount;
}
var principalPaid = 0;
var actualCashPaidForThisDebt = 0;
if (debt.balance + interestThisMonth <= paymentTowardsThisDebt) {
actualCashPaidForThisDebt = debt.balance + interestThisMonth;
principalPaid = debt.balance;
debt.balance = 0;
debtsPaidThisMonth.push(debt.name);
currentSnowballAmount += debt.originalMinPayment;
} else {
var potentialPrincipalPayment = paymentTowardsThisDebt – interestThisMonth;
if (potentialPrincipalPayment < 0) {
actualCashPaidForThisDebt = paymentTowardsThisDebt;
principalPaid = 0;
debt.balance += (interestThisMonth – paymentTowardsThisDebt);
} else {
principalPaid = potentialPrincipalPayment;
actualCashPaidForThisDebt = paymentTowardsThisDebt;
debt.balance -= principalPaid;
}
}
monthPrincipalPaid += principalPaid;
monthTotalPayment += actualCashPaidForThisDebt;
totalPrincipalPaidOverall += principalPaid;
currentMonthDebtDetails.push({
name: debt.name,
payment: actualCashPaidForThisDebt,
balance: debt.balance
});
}
totalCashPaidOverall += monthTotalPayment;
monthlySchedule.push({
month: totalMonths,
totalPayment: monthTotalPayment,
interestAccruedThisMonth: monthInterestAccrued,
principalPaidThisMonth: monthPrincipalPaid,
debts: currentMonthDebtDetails,
debtsPaidOff: debtsPaidThisMonth
});
}
var resultDiv = document.getElementById("snowballResult");
var scheduleDiv = document.getElementById("snowballSchedule");
var scheduleBody = document.getElementById("scheduleBody");
resultDiv.style.display = "block";
scheduleDiv.style.display = "block";
scheduleBody.innerHTML = "";
var years = Math.floor(totalMonths / 12);
var months = totalMonths % 12;
var payoffTimeString = "";
if (totalMonths === 0 && activeDebts.every(function(debt) { return debt.balance = maxMonths) {
payoffTimeString = "More than " + (maxMonths / 12) + " years (debt may be growing or very slow payoff)";
} else {
if (years > 0) {
payoffTimeString += years + " year" + (years === 1 ? "" : "s");
}
if (months > 0) {
if (years > 0) payoffTimeString += " and ";
payoffTimeString += months + " month" + (months === 1 ? "" : "s");
}
}
document.getElementById("totalPayoffTime").innerText = payoffTimeString;
document.getElementById("totalInterestPaid").innerText = "$" + totalInterestAccruedOverall.toFixed(2);
document.getElementById("totalAmountPaid").innerText = "$" + totalCashPaidOverall.toFixed(2);
monthlySchedule.forEach(function(monthData) {
var row = scheduleBody.insertRow();
row.insertCell(0).innerText = monthData.month;
row.insertCell(1).innerText = "$" + monthData.totalPayment.toFixed(2);
row.insertCell(2).innerText = "$" + monthData.interestAccruedThisMonth.toFixed(2);
row.insertCell(3).innerText = "$" + monthData.principalPaidThisMonth.toFixed(2);
row.insertCell(4).innerText = monthData.debtsPaidOff.length > 0 ? monthData.debtsPaidOff.join(", ") : "-";
var remainingBalancesText = monthData.debts.map(function(debt) {
return debt.name + ": $" + Math.max(0, debt.balance).toFixed(2);
}).join("");
row.insertCell(5).innerHTML = remainingBalancesText;
});
}