Vacancy rate is one of the three inputs that can swing an investment analysis from a buy to a pass. The other two - rent and expenses - are relatively observable. Vacancy is where analysts hide optimism. A 5% vacancy assumption is standard in most proformas. An 8% assumption is more honest for many markets in 2026. On a $1.5M acquisition with $120,000 in gross potential rent, that 3-point difference represents $3,600 in annual lost revenue - which changes NOI by $3,600, which changes value at a 6.5% cap rate by roughly $55,000. Apply it across a 10-property portfolio and the compounding effect on total returns is significant.

The problem is that vacancy rate is genuinely hard to measure at the neighborhood level. Most analysts fall back on national averages or use the same 5% placeholder they have used for years. This post covers four methods for actually estimating local vacancy - their mechanics, limitations, and when to use each one.

Why Vacancy Rate Matters More Than Most Analysts Acknowledge

Standard underwriting uses a single vacancy rate applied uniformly across all income: gross potential rent times (1 - vacancy rate) equals effective gross income. In reality, vacancy has two components that interact differently:

Physical vacancy is the percentage of units literally unoccupied at any given time. A 100-unit building with 7 empty units has 7% physical vacancy.

Economic vacancy is broader: it includes physical vacancy plus units occupied by non-paying tenants (eviction in process), units with significant concessions (first month free = roughly 8.3% economic vacancy on an annual lease), and units being held off-market for renovation. Economic vacancy is almost always higher than physical vacancy - often by 2-4 percentage points.

Most proformas use a single vacancy figure that is supposed to proxy for economic vacancy. The question is where that number comes from. Here are four methods, from most accessible to most accurate.

Method 1: Census ACS Vacancy Data

What It Measures

The Census Bureau's American Community Survey asks households whether rental units in their building are vacant. The ACS vacancy rate specifically captures structural vacancy - units that are available for rent but unoccupied. It does not capture economic vacancy from concessions or non-paying occupants.

How to Access It

The Census API at api.census.gov provides ACS vacancy data. The relevant variable is B25004_002E (vacant for rent) divided by B25002_003E (total renter-occupied + vacant for rent). Here is a simple Python call:

import requests

def get_acs_vacancy_rate(state_fips: str, county_fips: str, tract: str) -> float:
    """
    Pull ACS vacancy rate for a specific census tract.
    Returns vacancy rate as a decimal (e.g., 0.065 for 6.5%).
    """
    base = "https://api.census.gov/data/2023/acs/acs5"
    params = {
        "get": "B25004_002E,B25002_003E",
        "for": f"tract:{tract}",
        "in": f"state:{state_fips} county:{county_fips}",
        "key": "YOUR_CENSUS_API_KEY"  # Free at api.census.gov/data/key_signup.html
    }
    response = requests.get(base, params=params)
    response.raise_for_status()
    data = response.json()

    # data[1] is the first data row (data[0] is header)
    vacant_for_rent = int(data[1][0])
    total_rental_units = int(data[1][1])

    if total_rental_units == 0:
        return None

    return vacant_for_rent / total_rental_units

To get the FIPS codes for a specific address, use the Census Geocoder API at geocoding.geo.census.gov/geocoder. It accepts a street address and returns state, county, and tract FIPS.

Limitations

ACS 5-year estimates have a 2-3 year publication lag. The 2023 ACS 5-year estimates were published in December 2024 and use survey data from 2019-2023. In a market that experienced significant supply delivery in 2024-2025 (Sun Belt metros, particularly Austin, Nashville, and Phoenix), ACS vacancy data is meaningfully stale. The 1-year ACS estimates have a shorter lag but are only available at the county level and above - not census tract.

ACS also conflates structural vacancy (units truly available for rent) with frictional vacancy (units between tenants in the normal turnover process). A healthy market has 3-5% frictional vacancy even with zero excess supply. ACS cannot distinguish between a market that is perfectly balanced and one that is genuinely oversupplied.

Method 2: Days-on-Market Proxy

The Logic

If units are sitting vacant for longer before renting, effective vacancy is elevated. Median days-on-market for active listings is therefore a proxy for current-period vacancy conditions - it reflects real-time supply/demand balance without the lag of survey data.

The Calculation

Pull all active rental listings in your target submarket (zip code or 0.5-mile radius). Record the list date for each. Calculate days since listing. Then:

In a healthy market with 5-6% vacancy, roughly 10-15% of active listings will have been on market over 45 days (normal turnover variation). When that percentage climbs above 25-30%, something has changed - either supply has increased, demand has softened, or both.

Limitations

Stale listings skew the signal. Some landlords leave listings active indefinitely even after they have informally filled the unit. In markets where Zillow and Apartments.com listings are not promptly removed after leasing, DOM data overstates vacancy. Cross-reference with listing count trends: if total active listings are growing month-over-month while DOM is also increasing, the vacancy signal is reliable. If listings are declining but DOM is increasing, the data quality may be questionable.

Method 3: Absorption Rate

What Absorption Rate Measures

Absorption rate measures how quickly available units are being leased: new listings added per month divided by leases signed per month. A rate of 1.0 means supply and demand are perfectly balanced. Below 1.0 means demand is outpacing new supply (tight market). Above 1.0 means supply is accumulating (soft market, rising vacancy).

This is the most direct measure of supply/demand dynamics, but it is also the hardest to calculate without MLS access. Signed leases are not publicly reported in most rental markets - unlike home sales, which are recorded at the county recorder's office.

Approximating Without MLS Access

You can approximate absorption rate using Zillow's listing history if you have historical data saved. The approach:

  1. Record the total count of active listings in a submarket at the start of Month 1
  2. Record total count at the start of Month 2
  3. Record any new listings that appeared during Month 1 (listings with a list date in Month 1)
  4. Estimate leases signed = (Month 1 count) + (new listings in Month 1) - (Month 2 count)
  5. Absorption rate = estimated leases / new listings in Month 1

This approximation has meaningful error bars because some listings that disappear were withdrawn rather than leased. But directionally, a market where this ratio is consistently above 1.0 for 3+ months is showing deteriorating absorption - a leading indicator of rising vacancy.

Method 4: API-Aggregated Vacancy Data

How Blended Vacancy Estimates Work

The most practical approach for programmatic analysis is a blended vacancy estimate that combines multiple signals into a single figure. The RentComp API vacancy_rate_pct field uses a three-source blend:

The result is a vacancy estimate that combines the methodological rigor of census data with the real-time sensitivity of listing behavior. Each estimate includes a confidence score based on comp count and data recency - low confidence when fewer than 8 active listings are in the radius, high confidence when 20+ comps are available with recent list dates.

Python Example: Pulling Vacancy and Using It in NOI Calculation

import requests

API_KEY = "your_api_key_here"
BASE_URL = "https://api.rentcompapi.com/v1"

def get_vacancy_and_noi(
    address: str,
    bedrooms: int,
    gross_potential_rent_annual: float,
    operating_expenses_annual: float
) -> dict:
    """
    Pull market vacancy estimate and calculate NOI under three scenarios.
    """
    response = requests.post(
        f"{BASE_URL}/comps",
        headers={"Authorization": f"Bearer {API_KEY}"},
        json={
            "address": address,
            "bedrooms": bedrooms,
            "radius_miles": 0.5,
            "include_market_stats": True
        }
    )
    response.raise_for_status()
    data = response.json()

    stats = data["market_stats"]
    market_vacancy = stats.get("vacancy_rate_pct", 0.065)  # Default 6.5% if unavailable
    confidence = stats.get("vacancy_confidence", "medium")

    # Three underwriting scenarios
    scenarios = {
        "standard":    market_vacancy,
        "conservative": market_vacancy + 0.02,   # +200bps
        "stress_test":  market_vacancy + 0.05,   # +500bps
    }

    results = {}
    for scenario_name, vacancy_rate in scenarios.items():
        egi = gross_potential_rent_annual * (1 - vacancy_rate)
        noi = egi - operating_expenses_annual
        cap_rate_implied = noi / (noi / 0.065)  # Simplified for illustration

        results[scenario_name] = {
            "vacancy_rate": f"{vacancy_rate:.1%}",
            "effective_gross_income": round(egi),
            "noi": round(noi),
            "vacancy_loss": round(gross_potential_rent_annual * vacancy_rate)
        }

    return {
        "address": address,
        "market_vacancy_pct": f"{market_vacancy:.1%}",
        "vacancy_confidence": confidence,
        "scenarios": results
    }

# Example
result = get_vacancy_and_noi(
    address="4422 Peachtree Rd NE, Atlanta, GA 30319",
    bedrooms=2,
    gross_potential_rent_annual=120000,   # 10 units x $1,000/mo avg
    operating_expenses_annual=45000
)

print(f"Market vacancy: {result['market_vacancy_pct']} (confidence: {result['vacancy_confidence']})\n")
for scenario, data in result["scenarios"].items():
    print(f"{scenario.upper()}")
    print(f"  Vacancy rate:    {data['vacancy_rate']}")
    print(f"  Vacancy loss:    ${data['vacancy_loss']:,}/yr")
    print(f"  EGI:             ${data['effective_gross_income']:,}/yr")
    print(f"  NOI:             ${data['noi']:,}/yr\n")

Metro-Level Vacancy Benchmarks for 2025/2026

National context helps calibrate local estimates. These benchmarks reflect approximate conditions as of early 2026:

These are metro-level averages. Submarket variation within a metro can be substantial - Austin's domain area Class A vacancy is very different from South Austin SFR vacancy.

Using Vacancy in Underwriting: Three Model Inputs

The most disciplined approach to vacancy in underwriting is to run three scenarios explicitly rather than anchoring on a single number:

Standard Model

Use the API-derived market vacancy estimate (or your best current estimate from the methods above). This represents your base case - the most likely outcome given current market conditions. Document your data source and date.

Conservative Model

Add 200 basis points (2 percentage points) to the standard estimate. This accounts for the fact that the subject property may underperform the market median - due to condition, management quality, or micro-location factors - and adds a buffer for market softening over the hold period. On a $1.5M property with $120,000 GPR, the difference between 6.5% and 8.5% vacancy is $2,400/year in NOI - which changes value by roughly $36,000 at a 6.5% cap rate.

Stress Test Model

Add 500 basis points to the standard estimate. This stress test answers: does this deal still work if vacancy spikes to near-recession levels? In the 2008-2009 recession, national rental vacancy peaked at approximately 11%. In markets with new supply delivering into a demand shock, 12-14% is possible. If your DSCR breaks below 1.0 at this stress vacancy, you need either more equity in the deal or a fundamentally different submarket.

Underwriting discipline: Run all three scenarios and document them in your acquisition memo. A deal that only works at standard vacancy - but breaks at conservative vacancy - is a deal with insufficient margin of safety. The stress test is not a prediction; it is a question about how much you can absorb before the deal stops covering debt service.

Vacancy estimation will never be perfectly precise at the neighborhood level. The best you can do is triangulate between methods - use ACS as a structural baseline, DOM analysis for current-period signal, and blended API data for a single defensible number - and then underwrite conservatively around that estimate. For how vacancy feeds into the broader accuracy of rent estimates, see our post on best practices for rent estimate accuracy. For how to compare methodologies between manual analysis and API-driven approaches, see our post on rental comp API vs manual comps.

The RentComp API returns the vacancy_rate_pct field on every comp call, with confidence scoring so you know when to rely on it and when to supplement with additional research. For developers building underwriting tools, it removes one of the last inputs that typically requires a manual lookup or a stale assumption.

Ready to Pull Rental Comps via API?

Join the waitlist and get 80% off founding member pricing - for life.

Join the Waitlist