Analyze your potential real estate investment deals with precision. This calculator helps real estate investors determine the viability of a rental property by calculating key metrics like Monthly Cash Flow, Cash-on-Cash Return, and Cap Rate.
Please enter valid numerical values for all fields.
30 Years
15 Years
10 Years
Operating Expenses (Monthly)
Investment Analysis
Net Monthly Cash Flow$0.00
Cash-on-Cash Return (Annual)0.00%
Cap Rate0.00%
Total Monthly Expenses$0.00
Monthly Mortgage P&I$0.00
Understanding Your Rental Property Investment
Investing in real estate is a numbers game. To ensure you are buying an asset rather than a liability, it is crucial to understand the key metrics generated by our Rental Property ROI Calculator.
1. Net Monthly Cash Flow
This is arguably the most important metric for buy-and-hold investors. It represents the money left in your pocket after all expenses (mortgage, taxes, insurance, maintenance, vacancy reserves, etc.) are paid. A positive cash flow means the property is generating income, while negative cash flow means you are paying out of pocket to hold the property.
Formula:Total Monthly Income – Total Monthly Expenses (including debt service)
2. Cash-on-Cash Return (CoC)
Cash-on-Cash return measures the annual return you are making on the actual cash you invested. Unlike ROI, which might look at the total loan amount, CoC focuses only on your down payment, closing costs, and rehab costs. It allows you to compare real estate returns against other investment vehicles like stocks or bonds.
Target: Many investors aim for a CoC return between 8% and 12%, though this varies by market strategy.
3. Cap Rate (Capitalization Rate)
The Cap Rate helps you evaluate a property's profitability independent of financing. It indicates the rate of return on an investment assuming the property was purchased entirely with cash. This metric is essential for comparing similar properties in the same area.
Formula:Net Operating Income (NOI) / Current Market Value
Estimating Expenses Correctly
One of the biggest mistakes new investors make is underestimating operating expenses. Always account for:
Vacancy: Even in hot markets, tenants move out. Budgeting 5-8% helps cover turnover periods.
Maintenance: Roofs leak and toilets break. Setting aside 10-15% of rent ensures you aren't caught off guard.
Management Fees: Even if you self-manage now, calculating this (typically 8-10%) ensures the deal still works if you hire a pro later.
function calculateROI() {
// Get Input Values
var purchasePrice = parseFloat(document.getElementById('purchasePrice').value);
var downPayment = parseFloat(document.getElementById('downPayment').value);
var closingCosts = parseFloat(document.getElementById('closingCosts').value);
var interestRate = parseFloat(document.getElementById('interestRate').value);
var loanTerm = parseFloat(document.getElementById('loanTerm').value);
var monthlyRent = parseFloat(document.getElementById('monthlyRent').value);
var propertyTax = parseFloat(document.getElementById('propertyTax').value);
var insurance = parseFloat(document.getElementById('insurance').value);
var maintenance = parseFloat(document.getElementById('maintenance').value);
var vacancyRate = parseFloat(document.getElementById('vacancyRate').value);
var managementFee = parseFloat(document.getElementById('managementFee').value);
var hoa = parseFloat(document.getElementById('hoa').value);
// Validation
if (isNaN(purchasePrice) || isNaN(downPayment) || isNaN(monthlyRent)) {
document.getElementById('errorMsg').style.display = 'block';
document.getElementById('results').style.display = 'none';
return;
} else {
document.getElementById('errorMsg').style.display = 'none';
}
// Default defaults for empty optional fields
if (isNaN(closingCosts)) closingCosts = 0;
if (isNaN(propertyTax)) propertyTax = 0;
if (isNaN(insurance)) insurance = 0;
if (isNaN(maintenance)) maintenance = 0;
if (isNaN(vacancyRate)) vacancyRate = 0;
if (isNaN(managementFee)) managementFee = 0;
if (isNaN(hoa)) hoa = 0;
// 1. Calculate Mortgage Payment (Principal & Interest)
var loanAmount = purchasePrice – downPayment;
var monthlyRate = (interestRate / 100) / 12;
var numberOfPayments = loanTerm * 12;
var mortgagePayment = 0;
if (interestRate > 0) {
mortgagePayment = loanAmount * (monthlyRate * Math.pow(1 + monthlyRate, numberOfPayments)) / (Math.pow(1 + monthlyRate, numberOfPayments) – 1);
} else {
mortgagePayment = loanAmount / numberOfPayments;
}
// 2. Calculate Operating Expenses
var vacancyCost = monthlyRent * (vacancyRate / 100);
var managementCost = monthlyRent * (managementFee / 100);
var totalOperatingExpenses = propertyTax + insurance + maintenance + vacancyCost + managementCost + hoa;
var totalExpensesWithMortgage = totalOperatingExpenses + mortgagePayment;
// 3. Calculate Cash Flow
var monthlyCashFlow = monthlyRent – totalExpensesWithMortgage;
var annualCashFlow = monthlyCashFlow * 12;
// 4. Calculate Net Operating Income (NOI)
// NOI = Income – Operating Expenses (Excluding Mortgage)
var annualNOI = (monthlyRent * 12) – (totalOperatingExpenses * 12);
// 5. Calculate Cash on Cash Return
var totalCashInvested = downPayment + closingCosts;
var cashOnCash = 0;
if (totalCashInvested > 0) {
cashOnCash = (annualCashFlow / totalCashInvested) * 100;
}
// 6. Calculate Cap Rate
var capRate = 0;
if (purchasePrice > 0) {
capRate = (annualNOI / purchasePrice) * 100;
}
// Update UI
document.getElementById('monthlyCashFlow').innerText = '$' + monthlyCashFlow.toFixed(2);
document.getElementById('cashOnCash').innerText = cashOnCash.toFixed(2) + '%';
document.getElementById('capRate').innerText = capRate.toFixed(2) + '%';
document.getElementById('totalExpenses').innerText = '$' + totalExpensesWithMortgage.toFixed(2);
document.getElementById('mortgagePayment').innerText = '$' + mortgagePayment.toFixed(2);
// Style adjustments for positive/negative cash flow
var cashFlowCard = document.getElementById('card-cashflow');
if (monthlyCashFlow >= 0) {
cashFlowCard.classList.remove('negative');
cashFlowCard.classList.add('positive');
} else {
cashFlowCard.classList.remove('positive');
cashFlowCard.classList.add('negative');
}
document.getElementById('results').style.display = 'block';
}