How every number on this site is calculated
HomeStats is free because the inputs are free. Every figure here comes from a named public dataset, gets transformed by a formula we print on the page, and lands in JSON anyone can download. This page is the index to those formulas, the explanation of the one benchmark that several pages share, and an honest list of the defects we know about in our own data.
Market data as of May 31, 2026. Pipeline last run July 30, 2026. Coverage: 51 states, 3,073 counties, 18,052 cities.
Method pages
How housing overvaluation is calculated here
Several pages on this site describe a market as overvalued or undervalued. They all use the same arithmetic, and it is deliberately dull:
overvaluation % = 100 × (region ratio ÷ cross-sectional median of all states − 1)
The region ratio is one of two things. Price-to-income is the median sale price divided by median household income (Census ACS 5-year table B19013). Price-to-rent is the median sale price divided by twelve months of rent, so it reads as years of gross rent to buy the house.
A worked example from the current snapshot: California carries a price-to-income ratio of 9.21, against a national state median of 5.260. That is +75.1% versus the median state. Not "+75.1% overvalued in absolute terms" — +75.1% relative to the middle state in the same snapshot. The distinction matters, and it is the reason we phrase results that way everywhere.
Why a cross-sectional median instead of a long-run average
The honest answer is that no long-run price-to-income or price-to-rent level anchor exists in this dataset.
An exhaustive key scan of a state file for anything matching longterm | historic | baseline | anchor | norm
returns exactly two hits, and both are about inventory and days on market, not valuation. The FHFA House Price Index we
carry reaches back only to 2016 nationally and 2023 per state, and household income arrives as a single ACS snapshot with no
time series at state grain. You cannot reconstruct a decades-long price-to-income level from that, so we do not pretend to.
What we can do is compare every region to the middle of the current national distribution, print the formula, and disclose the denominator. A reader can download the same file and reproduce the benchmark in one line. That is a weaker claim than "37% above fair value," and it is the claim the data actually supports.
What we deliberately did not use
- Long-run price growth rates.
src/lib/forecast.jsships a per-state FHFA 1991–2024 CAGR table (national 4.40%, California 5.73%, 53 keys including a national fallback). That is a growth rate, not a level, so it cannot anchor a ratio. It is used only by the forecast, and it is cited to FHFA as an external table rather than presented as pipeline output. - The 3.5× / 5× / 7× price-to-income bands. These appear in the crash-risk normalizer and in the "historically affordable markets sit near 3–4×, above 5× is stretched, above 6× is severely overvalued" language already published on the state and county detail pages. They are Shiller/IMF-flavored judgment thresholds, not benchmarks computed from anything in this repository. We keep using them because consistency across pages is worth more than novelty, but they are labeled as thresholds everywhere they appear, including here.
- FHFA HPI as a level anchor. Forty national quarters and twelve state quarters is not a long run. We use HPI for drawdown and year-over-year change, which those windows support, and not for valuation levels, which they do not.
Median, not mean
The pipeline already ships unweighted means in data/national/index.json under stateAverages. We do
not benchmark against them, because both ratio distributions are right-skewed and a mean benchmark quietly inflates every
overvaluation figure. Here are both numbers side by side, recomputed at build time:
| Ratio | Shipped mean | Recomputed mean | Median (used here) | Mean vs. median |
|---|---|---|---|---|
| Price-to-income | 5.44 | 5.44 | 5.260 | +3.4% |
| Price-to-rent (years) | 22.33 | 22.33 | 21.645 | +3.2% |
Benchmarking against the mean would overstate every overvaluation reading by roughly 3.2% to 3.4% on the current snapshot.
Denominators, disclosed
Price-to-income is computed across n=50 states and price-to-rent across
n=50, not 51.
The Columbia row is excluded because its region file carries
valueToIncome, valueToRent, rent and buyVsRent as literal nulls with an
empty census object. Averaging over a null is how a benchmark silently drifts, so we drop the row and name the row we
dropped.
One consequence worth flagging: the pipeline's own stateAverages block uses different denominators for
different fields. valueToIncome and valueToRent carry count 50, while
medianPrice carries count 51. The excluded row is in one set and not the other, so those averages
are not strictly comparable to each other. Ours are computed over a single stated set.
Every other derived metric, and its formula
The overvaluation section above covers price-to-income and price-to-rent. These are the rest of the numbers this site
calculates rather than reads straight from a source file. Each one is stated as the pipeline actually computes it, in
scripts/fetch-data.mjs, with the assumptions that are baked in rather than configurable.
Buy-vs-rent ratio
buyVsRent = monthly PITI ÷ monthly ZORI rent
Below 1.0 means the modeled monthly cost of owning is lower than the modeled monthly cost of renting. PITI is built from a fixed set of assumptions: 80% loan-to-value, a 6.5% 30-year fixed rate, 360 payments, property tax at 1.2% of price a year, and insurance at 0.5% of price a year.
Two things to know before you lean on it. The 6.5% rate is hard-coded at pipeline time, not the live rate, so the stored value drifts as rates move; individual state pages recompute it against the current rate. And PITI here is only principal, interest, tax and insurance. It excludes HOA dues, PMI, maintenance and closing costs, all of which fall on the owning side of the comparison. The ratio is therefore optimistic about owning by a margin that grows with HOA-heavy housing stock.
Single-family vs condo gap
gap = single-family YoY price change − condo YoY price change
Positive means single-family homes are outperforming condos. A wide positive gap usually points at condo-specific stress rather than general market strength, because HOA dues, insurance availability and lender treatment of a building all hit condos first and do not show up in a headline all-residential price.
Inventory surplus
inventorySurplusPct = (current inventory − mean inventory across the trend) ÷ that mean
Above +0.10 reads as surplus and buyer leverage; below −0.10 reads as deficit. The denominator is the mean of every month present in that geography's trend series, which is 60 months at most. We describe it as a trend average rather than a long-run average on purpose: five years is not a housing cycle, and a market that has been oversupplied for the whole window will show a surplus near zero because the window itself is the baseline.
Days-on-market spike
domSpikePct = (current days on market − trailing 24-month mean) ÷ that mean
Above +0.20 while days on market is also at or above 60 is the combination worth paying attention to. Either signal alone is weak: a spike off a very fast base still means homes are selling quickly, and a high absolute number is normal in markets that have always been slow.
HomeStats market score
score = 50, adjusted in steps, clamped to 0–100
Higher means more buyer-friendly. This is not a weighted average. It starts every geography at 50 and moves it up or down in fixed increments as each input crosses a threshold, then clamps the result. The inputs are year-over-year price change, median-sale-price year-over-year, days on market, price-drop share, sale-to-list ratio, and inventory year-over-year. Where state-level context exists, it also moves on price-to-income and on the share of local occupations that can afford the median home.
Because the steps are fixed sizes rather than proportional, a market sitting just on either side of a threshold can differ by several points on a difference that is not meaningful. Treat the score as a coarse sort, not a measurement, and read the underlying fields on the geography's own page before drawing a conclusion from it.
Boomer and millennial owner share
boomerOwnerPct = (owners 65–74 + 75–84 + 85+) ÷ all owner householders
millennialOwnerPct = (owners 35–44 + 45–54) ÷ all owner householders
Both from Census ACS table B25007, which counts owner-occupied householders by age band. The bands are the ones the table publishes, so these are age brackets rather than true generational cohorts.
The "millennial" label is the weaker of the two. In 2026 the 45–54 bracket is Generation X, not millennials, so this field is better read as "owners aged 35 to 54" than as a generational measure. We kept the field name because it is what the data files and the API already return, and renaming it would break anything built against them. The boomer band is a closer fit.
Known limitations in the data we publish
None of the following is a secret we were forced to admit. Publishing it is the point. If a number on this site is shakier than it looks, you should be able to find that out from us rather than from a surprise.
- The market as-of date and the pipeline run date are different. Redfin market data is currently as of May 31, 2026, while the pipeline last ran July 30, 2026. Not fully contained yet. The leaderboard and analysis pages render the market period and label the run date separately, which is the behavior we want, because a fresh build should not make stale data look new. Two headers still show only the run timestamp: the front-page snapshot, which currently reads "Updated July 30, 2026" over figures that describe May 31, 2026, and the reports page. Both are being changed. Where the distinction matters, trust the market period stated here rather than an "updated" line.
- County market periods are not uniform. 2,850 of 3,073 counties sit at the latest period (May 31, 2026); the remaining 223 lag across 30 older periods, the oldest reaching back to September 30, 2020. Partly contained. The county tables built on period-sensitive Redfin market fields — months of supply and price cuts — drop every county whose reporting month is not the latest one, and each says so on the page along with how many rows that removed. County rankings built on Census demographic fields rather than a reporting month, such as pre-1940 housing share or ownership rate, do not apply that filter because those inputs are not month-stamped. The exception worth flagging is distress watch, which mixes month-stamped inventory and days-on-market signals into its score without a freshness filter; a lagging county there is scored on older market mechanics. An unfiltered county table silently mixes 2026 data with data several years old.
- Counties and cities have no local rent series. City price-to-rent divides a city price by the state ZORI
mean; the city files carry a
rentSourcefield that says exactly that. Counties carry no rent field at all. We publish no county price-to-rent ratio at all, and no leaderboard that ranks cities by price-to-rent. Two places do still surface the city field: the city detail pages print it as a single labeled metric, and short-term-rental viability uses its reciprocal as one input to a composite score and shows the resulting gross long-term yield in a column. Both are reading a city price against a state rent, so read them as a price signal with a rent-shaped label, not as a local rent measurement. A price ranking wearing a rent label is worse than no ranking. - The stored
rentYieldfield was wrong by a factor of twelve. It was computed as12 ÷ valueToRenton the assumption thatvalueToRentis a monthly ratio. It is annual, so the correct gross yield is1 ÷ valueToRent. Every state read twelve times too high — Alabama showed roughly 63% gross yield instead of 5.3%. Fixed in the data pipeline, effective the next weekly refresh. Because every value cleared the 7% green cutoff in the map's rent-yield shading, that layer previously colored all 51 states identically and carried no information; it reads correctly once the refreshed data lands. The valuation page is unaffected either way — it computes1 ÷ valueToRentitself and prints the formula rather than reading the stored field. - Some national monthly series carry duplicate dates. 6 of the
14 monthly series in
data/national/index.jsonare affected: medianSalePrice, inventory, daysOnMarket, homesSold, priceDropPct, saleToListRatio. Each holds 60 entries across only 30 unique dates, with the two readings for a given month differing slightly and arriving in inconsistent order, so "the second row" is not reliably the newer one. The remaining 8 series carry one row per date and are unaffected. Not fully contained yet. The raw-data page dedupes by date, keeps the last row for each date, and says so. The chart and the month-over-month deltas on the dashboard still read the raw array, which means that sawtooth is an artifact rather than a market signal and the "since last month" figure is comparing two readings of the same month. If you are rebuilding from the file yourself, dedupe by date first. - Metros and ZIP codes are not published yet. The current build carries 925 metros and 16,386 ZIP codes. Pages that would consume them render an empty state rather than failing, and no page presents a metro or ZIP figure derived from a coarser geography.
Common questions
- How is housing overvaluation calculated?
- Overvaluation % = 100 × (region ratio ÷ cross-sectional median of all states − 1). The ratio is either price-to-income (median sale price ÷ median household income) or price-to-rent (median sale price ÷ annual rent). On the May 31, 2026 snapshot the state price-to-income median is 5.260 across 50 states and the price-to-rent median is 21.645 across 50 states. Nothing is hidden: you can download the same file and recompute the benchmark yourself.
- What benchmark does HomeStats use for overvaluation?
- The cross-sectional median of all states in the current snapshot, not a long-run historical average. We use the median rather than the mean because both ratio distributions are right-skewed: the unweighted mean price-to-income is 5.44 against a median of 5.26, and the mean price-to-rent is 22.33 against a median of 21.64. Benchmarking against the mean would inflate every overvaluation figure by roughly 3.2% to 3.4%. Denominator is n=50 for price-to-income and n=50 for price-to-rent, excluding Columbia.
- Why don’t you publish a county price-to-rent ratio?
- Because no county-level rent series exists in the public sources we consume. Rent comes from the Zillow Observed Rent Index, which we can only resolve to state grain. Dividing a county price by its state rent would produce a county price ranking wearing a rent label, so we do not publish one. City files do carry the field, computed against that same state rent, and we publish no leaderboard ranking cities by it — the city detail pages print it as a single labeled metric and the short-term-rental page uses its reciprocal as one score input. Read those as a price signal carrying a rent-shaped label.
- Is HomeStats methodology open?
- Yes. Every formula is printed on the page that uses it, the scoring libraries live in the public repository, and the underlying JSON is served at /api/index.json with no key and no signup. This page also lists the known defects in our own data, which is the part most sites leave out. Market data is as of May 31, 2026; the pipeline last ran July 30, 2026.
Sources
The 17 upstream datasets this pipeline reads, taken from data/meta.json rather than hand-written,
so this list cannot drift away from what the build actually consumed.
- Redfin Weekly housing market data
- FRED (St. Louis Fed) Mortgage rates, economic indicators
- FHFA House Price Index
- U.S. Census Bureau Demographics, income, population
- Bureau of Labor Statistics Employment data
- HUD (Fair Market Rents) Rental market data by state
- BEA (Regional Price Parities) Cost of living index
- FBI Crime Data Violent and property crime rates
- EPA SDWIS Drinking water quality violations
- FEMA NRI National Risk Index — 18 natural hazard types
- FEMA NFIP National Flood Insurance Program policies and claims
- FEMA Disasters Disaster declarations by state
- EIA Residential electricity prices by state
- NOAA Climate normals — average annual temperature
- BLS OES Occupational employment and wage statistics — trade labor costs
- NAIC Homeowners insurance premiums by state
- Tax Foundation Effective property tax rates by state
Additional sources cited by the crash-risk composite
- IMF Global Housing Watch
- FHFA House Price Index
- Redfin Data Center
- NAR Realtors Confidence Index
- U.S. Census Building Permits Survey
- Shiller, Robert. "Irrational Exuberance" methodology (Yale Press)
Every page renders from the same JSON served at /api/index.json. No key, no signup, no rate limit. If you reproduce a number and get something different, that is a bug worth telling us about.