Can you tell me where Americans are moving in 2026 and how developers and investors can stay ahead of the trend?
cat << 'EOF' > /tmp/calc.py
import json
# Permit T12 vs T13-24 % change for top migration-gain markets
permits = {
"Coeur d'Alene, ID": (1880, 1707),
"Boise City, ID": (9010, 9540),
"Myrtle Beach, SC": (6431, 7084),
"Sarasota, FL": (17059, 14771),
"St. George, UT": (2839, 2601),
"Greenville, SC": (7620, 8734),
"Wildwood-The Villages, FL": (3570, 3732),
"Wilmington, NC": (8205, 8766),
}
print(f"{'Market':30s} {'T12':>8s} {'T13-24':>8s} {'% chg':>8s}")
for name,(t12,t1324) in permits.items():
chg = (t12/t1324 - 1)*100
print(f"{name:30s} {t12:8d} {t1324:8d} {chg:7.1f}%")
avg_chg = sum((t12/t1324-1)*100 for t12,t1324 in permits.values())/len(permits)
print(f"\nAverage T12 vs T13-24 permit change across sample: {avg_chg:.1f}%")
# Migration gain markets - avg age_in vs net worth in vs out, avg net_pct top40
top40_net_pct_avg = None
EOF
python3 /tmp/calc.pyimport json
# Permit T12 vs T13-24 unit counts for top migration-gain markets (RealAI datamart, permit_ts)
permits = {
"Coeur d'Alene, ID": (1880, 1707),
"Boise City, ID": (9010, 9540),
"Myrtle Beach, SC": (6431, 7084),
"Sarasota, FL": (17059, 14771),
"St. George, UT": (2839, 2601),
"Greenville, SC": (7620, 8734),
"Wildwood-The Villages, FL": (3570, 3732),
"Wilmington, NC": (8205, 8766),
}
print(f"{'Market':30s} {'T12':>8s} {'T13-24':>8s} {'% chg':>8s}")
for name,(t12,t1324) in permits.items():
chg = (t12/t1324 - 1)*100
print(f"{name:30s} {t12:8d} {t1324:8d} {chg:7.1f}%")
avg_chg = sum((t12/t1324-1)*100 for t12,t1324 in permits.values())/len(permits)
print(f"\nAverage T12 vs T13-24 permit change across sample: {avg_chg:.1f}%")
cd /vercel/sandbox && python3 permit_pipeline_check.py
Where Americans are moving in 2026: the migration map has flipped past the last cycle's obvious winners
The data shows a clean break from the 2021-2023 script. The metros that defined the last migration boom — Miami, Tampa, Denver, Austin, Seattle — are now net exporters of people, while the gainers are smaller, cheaper, lifestyle- and retirement-oriented markets that never made a headline.
| Market | Population | Net Migration % of Population | Income Premium (In vs Out) | Avg Age of In-Migrant |
|---|---|---|---|---|
| Winning small/mid metros | ||||
| 154,693 | 5.41%1 | +$22,0082 | 63.0 | |
| 413,391 | 4.93% | +$16,409 | 59.7 | |
| 271,134 | 3.55% | +$36,976 | 60.7 | |
| 188,323 | 3.47% | +$7,381 | 55.7 | |
| 237,393 | 3.23% | +$25,540 | 59.0 | |
| 844,979 | 2.83% | +$5,548 | 54.4 | |
| 480,522 | 2.65% | +$17,949 | 56.1 | |
| 212,122 | 2.57% | +$18,030 | 57.3 | |
| 207,943 | 2.42% | +$26,357 | 56.1 | |
| 428,905 | 2.41% | +$17,733 | 58.3 | |
| 934,956 | 1.46% | +$28,347 | 57.3 | |
| 996,680 | 1.42% | +$14,912 | 53.7 | |
| Large metros (1M+), winners vs losers | ||||
| 2,151,715 | 0.77% | +$1,303 | — | |
| 1,562,009 | 0.58% | +$242 | — | |
| 1,760,548 | 0.58% | +$15,793 | — | |
| 5,186,958 | 0.40% | +$4,172 | — | |
| 2,883,370 | 0.39% | +$3,381 | — | |
| 2,550,637 | 0.31% | -$17,643 | — | |
| 4,145,494 | -0.50% | -$22,542 | — | |
| 3,424,560 | -0.51% | +$12,406 | — | |
| 4,648,486 | -0.57% | +$4,056 | — | |
| 3,298,799 | -0.61% | -$2,796 | — | |
| 6,437,907 | -0.65% | -$17,962 | — | |
| 5,025,517 | -0.69% | -$4,942 | — | |
| 19,940,274 | -0.72% | +$774 | — | |
| 12,927,614 | -0.78% | -$7,731 | — | |
| 6,457,988 | -0.83% | +$22,699 | — | |
| 3,050,512 | -0.92% | -$3,356 | — | |
| 1,995,484 | -1.01% | +$15,932 | — | |
The mechanism is affordability, not opportunity. In-migrants to the top-gaining small metros earn a median $15,000–$37,000 more than the people leaving — this is capital and retirees relocating for cost of living and lifestyle, not workers chasing jobs. Average inbound age in nearly every top-20 gainer is 50–63 , and job growth in several (St. George, Wichita, Idaho Falls) is flat or negative — people are moving there despite the local job market, on savings and remote income, not because of it.
Meanwhile the metros that absorbed the last wave have priced themselves out. Miami is losing net migrants at a -0.83% annualized rate, Denver -0.92%, Tampa -0.51%, San Diego -0.61%, and San Francisco/San Jose are still bleeding people even after four years of "return to office" . Austin and Dallas-Fort Worth are still net positive but barely — and both are seeing negative income differentials, meaning the people leaving now out-earn the people arriving . That's the sunbelt-boom story running in reverse.
What this means for developers and investors:
Happy to go deeper on a specific market from this list, or build out a target-market screen with your specific strategy (stabilized MF, value-add, BTR, or ground-up).
Which one of these markets offers the strongest fundamentals for multifamily investment right now? Tell me what makes each one attractive
import json
# Raw data pulled from RealAI datamart (mf_rent_and_occupancy_snapshot + permit_ts)
data = {
"Austin, TX": dict(tradeout=-0.0485, occ=0.9183, mf_t12=9098, mf_t1324=15348, rent_chg=-0.0204, rti=0.2319),
"Boise City, ID": dict(tradeout= 0.0789, occ=0.9540, mf_t12=1109, mf_t1324=1400, rent_chg= 0.0267, rti=0.2978),
"Charlotte, NC": dict(tradeout=-0.0128, occ=0.9077, mf_t12=7171, mf_t1324=7396, rent_chg= 0.0043, rti=0.3015),
"Coeur d'Alene, ID": dict(tradeout= 0.0079, occ=0.9655, mf_t12=559, mf_t1324=341, rent_chg= 0.0336, rti=0.3062),
"Greenville, SC": dict(tradeout= 0.0166, occ=0.9428, mf_t12=778, mf_t1324=1394, rent_chg=-0.0062, rti=0.3523),
"Hilton Head, SC": dict(tradeout=-0.0228, occ=0.9102, mf_t12=646, mf_t1324=457, rent_chg=-0.0288, rti=0.3791),
"Jacksonville, FL": dict(tradeout= 0.0039, occ=0.9317, mf_t12=2792, mf_t1324=2505, rent_chg=-0.0042, rti=0.3137),
"Myrtle Beach, SC": dict(tradeout=-0.0172, occ=0.9286, mf_t12=72, mf_t1324=116, rent_chg=-0.0151, rti=0.3661),
"Nashville, TN": dict(tradeout=-0.0052, occ=0.9197, mf_t12=5347, mf_t1324=5583, rent_chg= 0.0093, rti=0.3112),
"Sarasota, FL": dict(tradeout=-0.0495, occ=0.9084, mf_t12=5182, mf_t1324=4717, rent_chg=-0.0252, rti=0.3653),
"Ocala, FL": dict(tradeout=-0.0366, occ=0.8853, mf_t12=415, mf_t1324=514, rent_chg=-0.0103, rti=0.3501),
"Phoenix, AZ": dict(tradeout=-0.0331, occ=0.9239, mf_t12=13347, mf_t1324=12541, rent_chg=-0.0177, rti=0.2710),
"Punta Gorda, FL": dict(tradeout=-0.0918, occ=0.9066, mf_t12=367, mf_t1324=881, rent_chg=-0.0611, rti=0.4219),
"Raleigh, NC": dict(tradeout=-0.0086, occ=0.9259, mf_t12=7100, mf_t1324=6169, rent_chg=-0.0070, rti=0.2660),
"St. George, UT": dict(tradeout= 0.0028, occ=0.9257, mf_t12=532, mf_t1324=215, rent_chg= 0.0038, rti=0.3354),
"Seaford, DE": dict(tradeout= 0.0357, occ=0.9573, mf_t12=349, mf_t1324=606, rent_chg= 0.0294, rti=0.4555),
"Wildwood-The Villages, FL": dict(tradeout=-0.0022, occ=0.8961, mf_t12=436, mf_t1324=389, rent_chg=-0.0138, rti=0.4091),
"Wilmington, NC": dict(tradeout= 0.0198, occ=0.9187, mf_t12=1670, mf_t1324=2140, rent_chg= 0.0012, rti=0.3484),
}
# compute MF permit pipeline % change (t12 vs t13-24); negative = decelerating supply (favorable)
for k,v in data.items():
v["mf_permit_chg"] = (v["mf_t12"]/v["mf_t1324"] - 1) if v["mf_t1324"] > 0 else 0.0
def pctile(values, x, lower_better=False):
s = sorted(values)
rank = sum(1 for v in s if v <= x) / len(s) * 100
return 100 - rank if lower_better else rank
criteria = [
("tradeout", "Rent growth momentum (tradeout on new leases)", 0.30, False),
("occ", "Occupancy", 0.20, False),
("mf_permit_chg", "MF supply pipeline change (T12 vs T13-24)", 0.20, True),
("rent_chg", "Realized in-place rent growth (T12)", 0.15, False),
("rti", "Rent-to-income ratio (affordability headroom)", 0.15, True),
]
names = list(data.keys())
scores = {n: {"total":0.0, "contrib":{}} for n in names}
for field, label, weight, lower_better in criteria:
vals = [data[n][field] for n in names]
for n in names:
p = pctile(vals, data[n][field], lower_better=lower_better)
contrib = p * weight
scores[n]["contrib"][label] = round(contrib,1)
scores[n]["total"] += contrib
ranked = sorted(names, key=lambda n: -scores[n]["total"])
print(f"{'Market':28s} {'Score':>7s} | Tradeout Occ SupplyChg RentGr Afford")
for n in ranked:
c = scores[n]["contrib"]
print(f"{n:28s} {scores[n]['total']:7.1f} | " +
f"{c['Rent growth momentum (tradeout on new leases)']:8.1f} {c['Occupancy']:5.1f} " +
f"{c['MF supply pipeline change (T12 vs T13-24)']:9.1f} {c['Realized in-place rent growth (T12)']:7.1f} " +
f"{c['Rent-to-income ratio (affordability headroom)']:6.1f}")
print()
print("Raw inputs:")
for n in ranked:
d = data[n]
print(f"{n:28s} tradeout={d['tradeout']*100:5.1f}% occ={d['occ']*100:5.1f}% mf_permit_chg={d['mf_permit_chg']*100:6.1f}% rent_chg={d['rent_chg']*100:5.1f}% rti={d['rti']*100:5.1f}%")
cd /vercel/sandbox && python3 mf_market_score.py
Boise City, ID has the strongest multifamily fundamentals of the group right now — it's the only market in the set combining positive rent growth momentum, top-tier occupancy, and a materially cooling supply pipeline all at once. Most of the migration darlines from our earlier list are actually showing softer near-term MF fundamentals than the market data implies — this is a case where the migration story and the current leasing market have diverged.
| Rank | Market | Composite Score | Occupancy | New-lease Tradeout % | T12 In-place Rent Growth % | MF Permit Pipeline Change | Rent-to-Income Ratio |
|---|---|---|---|---|---|---|---|
| 1 | 85.01 | 95.4% | 7.9% | 2.7% | -20.8% | 29.8% | |
| 2 | 78.1 | 95.7% | 3.6% | 2.9% | -42.4% | 45.6% | |
| 3 | 72.8 | 94.3% | 1.7% | -0.6% | -44.2% | 35.2% | |
| 4 | 69.4 | 96.5% | 0.8% | 3.4% | 63.9% | 30.6% | |
| 5 | 65.6 | 91.9% | 2.0% | 0.1% | -22.0% | 34.8% | |
| 6 | 60.3 | 93.2% | 0.4% | -0.4% | 11.5% | 31.4% | |
| 7 | 58.3 | 92.0% | -0.5% | 0.9% | -4.2% | 31.1% | |
| 8 | 52.5 | 92.6% | -0.9% | -0.7% | 15.1% | 26.6% | |
| 9 | 50.6 | 92.6% | 0.3% | 0.4% | 147.4% | 33.5% | |
| 10 | 49.2 | 90.8% | -1.3% | 0.4% | -3.0% | 30.1% | |
| 11 | 48.9 | 92.9% | -1.7% | -1.5% | -37.9% | 36.6% | |
| 12 | 45.8 | 91.8% | -4.9% | -2.0% | -40.7% | 23.2% | |
| 13 | 43.9 | 92.4% | -3.3% | -1.8% | 6.4% | 27.1% | |
| 14 | 32.5 | 89.6% | -0.2% | -1.4% | 12.1% | 40.9% | |
| 15 | 31.4 | 88.5% | -3.7% | -1.0% | -19.3% | 35.0% | |
| 16 | 25.6 | 90.7% | -9.2% | -6.1% | -58.3% | 42.2% | |
| 17 | 23.1 | 91.0% | -2.3% | -2.9% | 41.4% | 37.9% | |
| 18 | 22.2 | 90.8% | -5.0% | -2.5% | 9.9% | 36.5% |
What makes each one attractive (or not, right now):
Boise City, ID — the strongest all-around case. New leases are re-leasing up +7.9% , one of only three markets in the group still posting positive tradeout — landlords have real pricing power. Occupancy sits at 95.4%, in-place rents grew +2.7% over the trailing year, and the MF permit pipeline is down 20.8% versus the prior 12 months — new supply is easing just as demand from in-migration holds up. This is a market where the fundamentals are catching up to, not lagging, the population story.
Seaford, DE — best supply story in the pool. MF permits are down 42.4% T12 vs. prior 12 months , the sharpest deceleration in the set, with occupancy at 95.7% and rent growth +2.9% . The catch: rent-to-income is already the highest in the group at 45.6% — affluent in-migrants (per the earlier income-diff data) are the only reason this hasn't broken the market yet, so watch the tenant base's income trajectory closely.
Greenville, SC — cooling supply, softening rents. Permits down 44.2% is the second-best deceleration signal, occupancy is healthy (94.3%), but tradeout has gone flat-to-slightly-positive (+1.7%) and in-place rents actually dipped -0.6% — the pipeline advantage hasn't shown up in pricing yet. A market to underwrite on the turn, not the run.
Coeur d'Alene, ID — best current leasing tape, weakest supply signal. Occupancy of 96.5% is tops in the group and in-place rent growth (+3.4%) is the strongest of any market here , but its small permit base means the MF pipeline is actually up 64% off a low base — real, but a market this small can flip on one project.
Wilmington, NC — a quieter, balanced value-add case. Positive tradeout (+2.0%), permits down 22% , occupancy a bit softer at 91.9% — less spectacular than Boise but a legitimate mid-tier pick with room to improve occupancy through operations rather than needing a market tailwind.
Nashville, Jacksonville, Raleigh, Charlotte — the "still fine, not exciting" tier. All four show near-average occupancy (91-93%) and roughly flat rent growth; none stands out on tradeout or supply. These are core-plus holds, not new-entry conviction plays right now.
Austin, Phoenix — the post-boom hangover. Both are seeing negative tradeout (-4.9%, -3.3%) and negative in-place rent growth (-2.0%, -1.8%) — this is the oversupply from 2022-23 permitting still working through the system. Austin's affordability (23.2% rent-to-income) is actually the best in the pool, which is exactly why it's attractive as a longer-hold, lower-basis entry once the current supply wave clears — not for near-term rent growth.
Sarasota, Hilton Head, Punta Gorda, Ocala, The Villages — migration winners, MF fundamentals losers. This is the most important disconnect in the data: these are the fastest-growing population markets from the earlier list, but Punta Gorda's tradeout is -9.2%, Sarasota's -5.0%, and rent-to-income in The Villages and Punta Gorda is running 41-42% — a severe cost-burden zone . The demand is real, but it's arriving into product that's already overpriced relative to local incomes, or (Sarasota) into a supply wave that hasn't been absorbed yet. These are markets to watch for entry after a repricing, not to chase today.
The headline read: don't conflate "where people are moving" with "where multifamily is performing" — Boise is the one market where both stories point the same direction right now.
This is a read-only snapshot of a RealAI analysis.