How to Calculate Return on Investment (ROI) for Rental Properties
Investing in real estate is one of the most proven ways to build long-term wealth, but not every property is a "good" investment. To determine if a rental property is worth your capital, you must look beyond the monthly rent and analyze the full financial picture including debt service, operating expenses, and initial cash outlay.
Key Metrics Explained
Cap Rate (Capitalization Rate): This is the ratio of Net Operating Income (NOI) to the property purchase price. It measures the property's natural rate of return without considering mortgage debt. Formula: (Annual Income – Annual Expenses) / Purchase Price.
Cash Flow: This is the actual money left in your pocket each month after paying the mortgage, taxes, insurance, and setting aside money for repairs.
Cash on Cash (CoC) Return: This is arguably the most important metric for leveraged investors. It measures the annual cash flow relative to the actual cash you invested (down payment and closing costs).
Example Calculation
Suppose you purchase a duplex for $300,000 with a 20% down payment ($60,000).
If the total monthly rent is $2,500 and your total expenses (mortgage, tax, insurance, maintenance) are $2,100, your Monthly Cash Flow is $400.
Your annual cash flow would be $4,800. To find your Cash on Cash return: $4,800 / $60,000 = 8%. In many markets, a CoC return between 8% and 12% is considered a strong investment.
Don't Forget the "Hidden" Expenses
Novice investors often fail to account for Vacancy and Capital Expenditures (CapEx). Even if a tenant is in place today, you should budget at least 5-10% of gross rent for future months when the unit is empty or when the roof needs replacing. Our calculator includes a "Maintenance & Vacancy" field to ensure your ROI projections stay realistic.
function calculateRentalROI() {
var purchasePrice = parseFloat(document.getElementById('purchasePrice').value);
var downPercent = parseFloat(document.getElementById('downPaymentPercent').value);
var interestRate = parseFloat(document.getElementById('interestRate').value) / 100 / 12;
var termMonths = parseFloat(document.getElementById('loanTerm').value) * 12;
var monthlyRent = parseFloat(document.getElementById('monthlyRent').value);
var annualTax = parseFloat(document.getElementById('propertyTax').value);
var monthlyInsurance = parseFloat(document.getElementById('insurance').value);
var maintPercent = parseFloat(document.getElementById('maintenancePercent').value) / 100;
if (isNaN(purchasePrice) || isNaN(monthlyRent)) {
alert("Please enter valid numeric values.");
return;
}
// Loan Logic
var downPaymentAmount = purchasePrice * (downPercent / 100);
var loanAmount = purchasePrice – downPaymentAmount;
var monthlyMortgage = 0;
if (interestRate > 0) {
monthlyMortgage = loanAmount * (interestRate * Math.pow(1 + interestRate, termMonths)) / (Math.pow(1 + interestRate, termMonths) – 1);
} else {
monthlyMortgage = loanAmount / termMonths;
}
// Expenses
var monthlyTax = annualTax / 12;
var monthlyMaint = monthlyRent * maintPercent;
var totalMonthlyExpenses = monthlyMortgage + monthlyTax + monthlyInsurance + monthlyMaint;
// Metrics
var monthlyCashFlow = monthlyRent – totalMonthlyExpenses;
var annualCashFlow = monthlyCashFlow * 12;
// Net Operating Income (Income – Expenses excluding Mortgage)
var annualNOI = (monthlyRent * 12) – (annualTax + (monthlyInsurance * 12) + (monthlyMaint * 12));
var capRate = (annualNOI / purchasePrice) * 100;
var cashOnCash = (annualCashFlow / downPaymentAmount) * 100;
// Display Results
document.getElementById('resMortgage').innerText = "$" + monthlyMortgage.toLocaleString(undefined, {minimumFractionDigits: 2, maximumFractionDigits: 2});
document.getElementById('resCashFlow').innerText = "$" + monthlyCashFlow.toLocaleString(undefined, {minimumFractionDigits: 2, maximumFractionDigits: 2});
document.getElementById('resCapRate').innerText = capRate.toFixed(2) + "%";
document.getElementById('resCoC').innerText = cashOnCash.toFixed(2) + "%";
document.getElementById('results').style.display = 'block';
document.getElementById('results').scrollIntoView({ behavior: 'smooth' });
}