Calculating cash flow is the fundamental step in evaluating any rental property investment. Cash flow represents the money left over after all operating expenses and mortgage payments have been made. A positive cash flow indicates a profitable month-to-month operation, while negative cash flow means the property costs you money to hold.
Key Metrics Explained
1. Net Operating Income (NOI)
NOI is a calculation used to analyze the profitability of income-generating real estate investments. It equals all revenue from the property, minus all necessary operating expenses.
Formula: (Rental Income – Vacancy Losses) – Operating Expenses
Note: NOI does not include mortgage payments (debt service). It is a pure measure of the property's efficiency.
2. Cash on Cash Return (CoC)
This metric measures the annual return the investor made on the property in relation to the amount of mortgage paid during the same year. It is considered one of the most important ROI metrics in real estate.
Example: If you invest $50,000 cash (down payment + closing costs) and the property generates $5,000 in annual cash flow, your CoC is 10%.
3. Cap Rate (Capitalization Rate)
The Cap Rate indicates the rate of return that is expected to be generated on a real estate investment property. It helps compare the profitability of different properties regardless of how they were financed (cash vs. loan).
Formula: (Net Operating Income / Current Market Value) × 100
A higher cap rate generally implies a better return but may come with higher risk or a less desirable location.
How to Use This Calculator
To get the most accurate results, ensure you are realistic with your expense estimates:
Vacancy Rate: Don't assume 100% occupancy. A standard safety margin is 5% to 8% (roughly 2-4 weeks of vacancy per year).
Maintenance: Properties degrade over time. Saving 5% to 10% of monthly rent for future repairs (HVAC, roof, plumbing) is prudent.
Management Fees: Even if you self-manage now, calculating a typical 8-10% management fee helps ensure the deal is good enough to support a manager later if you choose to outsource.
By inputting conservative numbers for expenses and realistic numbers for rent, you can determine if a property meets your investment criteria before making an offer.
function calculateRental() {
// 1. Retrieve Inputs
var price = parseFloat(document.getElementById('purchasePrice').value) || 0;
var downPercent = parseFloat(document.getElementById('downPayment').value) || 0;
var interestRate = parseFloat(document.getElementById('interestRate').value) || 0;
var termYears = parseFloat(document.getElementById('loanTerm').value) || 0;
var closingCosts = parseFloat(document.getElementById('closingCosts').value) || 0;
var rent = parseFloat(document.getElementById('monthlyRent').value) || 0;
var vacancyPercent = parseFloat(document.getElementById('vacancyRate').value) || 0;
var annualTax = parseFloat(document.getElementById('propertyTax').value) || 0;
var annualIns = parseFloat(document.getElementById('insurance').value) || 0;
var monthlyHOA = parseFloat(document.getElementById('hoa').value) || 0;
var maintPercent = parseFloat(document.getElementById('maintenance').value) || 0;
var mgmtPercent = parseFloat(document.getElementById('management').value) || 0;
// 2. Initial Investment Calculation
var downAmount = price * (downPercent / 100);
var loanAmount = price – downAmount;
var totalInitialInvestment = downAmount + closingCosts;
// 3. Mortgage Calculation (Principal & Interest)
var monthlyRate = (interestRate / 100) / 12;
var numPayments = termYears * 12;
var monthlyPI = 0;
if (interestRate > 0) {
monthlyPI = loanAmount * (monthlyRate * Math.pow(1 + monthlyRate, numPayments)) / (Math.pow(1 + monthlyRate, numPayments) – 1);
} else {
monthlyPI = loanAmount / numPayments;
}
// 4. Operating Expenses Calculation
// Vacancy is a loss of income, but mathematically treated as an expense deduction from Gross Rent
var vacancyCost = rent * (vacancyPercent / 100);
var maintCost = rent * (maintPercent / 100);
var mgmtCost = rent * (mgmtPercent / 100);
var monthlyTax = annualTax / 12;
var monthlyIns = annualIns / 12;
var totalOperatingExpenses = monthlyTax + monthlyIns + monthlyHOA + maintCost + mgmtCost + vacancyCost;
// 5. NOI Calculation (Monthly)
// NOI = Gross Income – Operating Expenses (Vacancy is already accounted for in totalOperatingExpenses logic as a cost)
// Alternatively: Effective Gross Income (Rent – Vacancy) – (Tax + Ins + HOA + Maint + Mgmt)
// Both result in same net number.
var monthlyNOI = rent – totalOperatingExpenses;
var annualNOI = monthlyNOI * 12;
// 6. Cash Flow Calculation
var totalMonthlyExpensesWithDebt = totalOperatingExpenses + monthlyPI;
var monthlyCashFlow = rent – totalMonthlyExpensesWithDebt;
var annualCashFlow = monthlyCashFlow * 12;
// 7. Key Metrics
var capRate = 0;
if (price > 0) {
capRate = (annualNOI / price) * 100;
}
var cashOnCash = 0;
if (totalInitialInvestment > 0) {
cashOnCash = (annualCashFlow / totalInitialInvestment) * 100;
}
// 8. Update DOM
var resContainer = document.getElementById('resultContainer');
var resCashFlow = document.getElementById('resCashFlow');
var resCoC = document.getElementById('resCoC');
var resCapRate = document.getElementById('resCapRate');
var resNOI = document.getElementById('resNOI');
var resTotalExp = document.getElementById('resTotalExp');
var resMortgage = document.getElementById('resMortgage');
var resInvestment = document.getElementById('resInvestment');
resContainer.style.display = 'block';
// Formatting currency and percent
var formatCurrency = new Intl.NumberFormat('en-US', { style: 'currency', currency: 'USD' });
resCashFlow.textContent = formatCurrency.format(monthlyCashFlow);
if (monthlyCashFlow < 0) {
resCashFlow.classList.add('metric-negative');
} else {
resCashFlow.classList.remove('metric-negative');
}
resCoC.textContent = cashOnCash.toFixed(2) + '%';
if (cashOnCash < 0) {
resCoC.classList.add('metric-negative');
} else {
resCoC.classList.remove('metric-negative');
}
resCapRate.textContent = capRate.toFixed(2) + '%';
resNOI.textContent = formatCurrency.format(monthlyNOI);
resTotalExp.textContent = formatCurrency.format(totalMonthlyExpensesWithDebt);
resMortgage.textContent = formatCurrency.format(monthlyPI);
resInvestment.textContent = formatCurrency.format(totalInitialInvestment);
}