Analyze cash flow, Cap Rate, and Cash on Cash Return for real estate investments.
Purchase Details
Loan Details
Income & Expenses
Monthly Cash Flow$0.00
Cash on Cash ROI0.00%
Cap Rate0.00%
Monthly Expenses$0.00
Mortgage Payment (P&I)$0.00
Total Cash Invested$0.00
Understanding Rental Property ROI
Investing in real estate is a powerful way to build wealth, but not every property is a good deal. To ensure your investment is profitable, you must move beyond the "gross rent" number and analyze the actual returns after all expenses. This Rental Property ROI Calculator helps investors determine the viability of a potential purchase by calculating three critical metrics: Cash Flow, Cap Rate, and Cash on Cash Return.
1. Monthly Cash Flow
Cash flow is the net amount of money left in your pocket at the end of every month. It is calculated by taking your total monthly rental income and subtracting all operating expenses and debt service (your mortgage payment).
Why it matters: Positive cash flow ensures the property pays for itself and provides you with passive income. Negative cash flow means you are losing money every month to hold the asset.
2. Cash on Cash Return (CoC ROI)
This is arguably the most important metric for investors using leverage (a mortgage). It measures the annual return you earn on the actual cash you invested (down payment + closing costs), rather than the total price of the home.
Formula: (Annual Cash Flow / Total Cash Invested) × 100
Example: If you invest $50,000 cash to buy a property and it generates $5,000 in net profit per year, your Cash on Cash ROI is 10%. This allows you to compare real estate returns against stocks or bonds.
3. Capitalization Rate (Cap Rate)
The Cap Rate measures the property's natural rate of return assuming you bought it in all cash. It is useful for comparing the profitability of different properties regardless of how they are financed.
Formula: (Net Operating Income / Purchase Price) × 100
Note: Net Operating Income (NOI) includes all expenses except the mortgage payment.
Estimating Expenses Correctly
New investors often overestimate profit by ignoring hidden costs. This calculator includes inputs for Vacancy (time between tenants) and Maintenance (repairs). A common rule of thumb is to set aside 10-15% of monthly rent for these two categories combined.
Disclaimer: This calculator is for educational purposes only. It estimates returns based on your inputs and does not guarantee future performance. Real estate investments carry risks; consult a financial advisor before investing.
function calculateRentalROI() {
// 1. Get Input Values
var price = parseFloat(document.getElementById('rp_price').value);
var downPercent = parseFloat(document.getElementById('rp_down_percent').value);
var closingCostsPercent = parseFloat(document.getElementById('rp_closing_costs').value);
var interestRate = parseFloat(document.getElementById('rp_rate').value);
var loanTermYears = parseFloat(document.getElementById('rp_term').value);
var monthlyRent = parseFloat(document.getElementById('rp_rent').value);
var taxPercent = parseFloat(document.getElementById('rp_tax').value);
var annualInsurance = parseFloat(document.getElementById('rp_insurance').value);
var monthlyHOA = parseFloat(document.getElementById('rp_hoa').value);
var maintVacancyPercent = parseFloat(document.getElementById('rp_maintenance').value);
// 2. Validation
if (isNaN(price) || isNaN(monthlyRent) || isNaN(downPercent)) {
alert("Please enter valid numbers for Price, Down Payment, and Rent.");
return;
}
// 3. Initial Calculations
var downPayment = price * (downPercent / 100);
var closingCosts = price * (closingCostsPercent / 100);
var totalCashInvested = downPayment + closingCosts;
var loanAmount = price – downPayment;
// 4. Mortgage Calculation (Monthly P&I)
var monthlyMortgage = 0;
if (loanAmount > 0) {
if (interestRate > 0) {
var monthlyRate = (interestRate / 100) / 12;
var totalPayments = loanTermYears * 12;
// M = P [ i(1 + i)^n ] / [ (1 + i)^n – 1 ]
monthlyMortgage = loanAmount * (monthlyRate * Math.pow(1 + monthlyRate, totalPayments)) / (Math.pow(1 + monthlyRate, totalPayments) – 1);
} else {
monthlyMortgage = loanAmount / (loanTermYears * 12);
}
}
// 5. Expense Calculations
var monthlyTax = (price * (taxPercent / 100)) / 12;
var monthlyInsurance = annualInsurance / 12;
var monthlyMaintVacancy = monthlyRent * (maintVacancyPercent / 100);
// Total Operating Expenses (excluding Mortgage) – Used for NOI
var monthlyOperatingExpenses = monthlyTax + monthlyInsurance + monthlyHOA + monthlyMaintVacancy;
// Total Monthly Expenses (including Mortgage) – Used for Cash Flow
var totalMonthlyExpenses = monthlyOperatingExpenses + monthlyMortgage;
// 6. Metric Calculations
var monthlyCashFlow = monthlyRent – totalMonthlyExpenses;
var annualCashFlow = monthlyCashFlow * 12;
// Cash on Cash ROI
var cocRoi = 0;
if (totalCashInvested > 0) {
cocRoi = (annualCashFlow / totalCashInvested) * 100;
}
// Net Operating Income (NOI)
var annualNOI = (monthlyRent * 12) – (monthlyOperatingExpenses * 12);
// Cap Rate
var capRate = 0;
if (price > 0) {
capRate = (annualNOI / price) * 100;
}
// 7. Update DOM
var formatter = new Intl.NumberFormat('en-US', {
style: 'currency',
currency: 'USD',
minimumFractionDigits: 2
});
document.getElementById('res_cashflow').innerText = formatter.format(monthlyCashFlow);
document.getElementById('res_coc').innerText = cocRoi.toFixed(2) + "%";
document.getElementById('res_cap').innerText = capRate.toFixed(2) + "%";
document.getElementById('res_expenses').innerText = formatter.format(totalMonthlyExpenses);
document.getElementById('res_mortgage').innerText = formatter.format(monthlyMortgage);
document.getElementById('res_investment').innerText = formatter.format(totalCashInvested);
// Add visual cues for positive/negative cashflow
var cashFlowEl = document.getElementById('res_cashflow');
if (monthlyCashFlow >= 0) {
cashFlowEl.classList.remove('negative');
cashFlowEl.classList.add('positive');
} else {
cashFlowEl.classList.remove('positive');
cashFlowEl.classList.add('negative');
}
// Show results
document.getElementById('rp_results').style.display = 'block';
}