← All studies · askamerica.ai

Disaster-driven exodus is real and accelerating — but concentrated in a handful of expensive counties, not a mass depopulation of "at-risk" America

Redfin/Census domestic migration (2025) + First Street flood-risk scores; AskAmerica IRS SOI county migration flows vs. FEMA/NOAA disaster data, 2012-2021

Disaster-Driven Exodus Is Real but Concentrated, Not a Mass Depopu… Redfin/Census domestic migration (2025) + First Street flood-risk scores; AskAmerica IRS SOI migration flows vs. FEMA/NOAA damage, 2012-2021 Net outflow, high-flood-risk counties, 2025 -63,357 people nearly 2x 2024's -34,099 Redfin analysis of Census domestic migration + First Street risk scores, top decile counties by share of homes at major/severe/extreme… Warehouse check: top-decile counties by cumulative storm damage per capita, 2012-2021 +610,711 people (+1.9%) IRS SOI migration flows, n=308 counties, baseline pop 32.8M — net INFLOW, dominated by large recovering Sunbelt metros (e.g. Harris… 2025's biggest LOSERS among high-flood-risk counties -80,000 -70,000 -60,000 -50,000 -40,000 -30,000 -20,000 -10,000 0 County Net domestic outflow Miami-Dade, FL Harris, TX Kings, NY Hudson, NJ Pinellas, FL Jefferson Parish, LA Marin, CA Orleans Parish, LA Collier, FL Monroe, FL Source: Redfin analysis of Census Bureau Vintage Population Estimates, domestic migration only 2025's biggest GAINERS among high-flood-risk counties 0 2,000 4,000 6,000 8,000 10,000 12,000 14,000 County Net domestic inflow St. Johns, FL Fort Bend, TX Lee, FL Brunswick, NC Charlotte, FL Volusia, FL Sussex, DE Sarasota, FL Flagler, FL Brazoria, TX All ten gaining counties have median list prices under $500K, vs. ~$1M+ in the biggest-losing counties AskAmerica · askamerica.ai
SVG

Summary

There is no across-the-board "mass depopulation" of disaster-hit counties. Two distinct things are true at once: (1) a real, accelerating exodus from the specific counties that combine high flood risk with high cost of living — 63,357 more people left than arrived in the nation's highest-flood-risk counties in the year ending mid-2025, nearly double the prior year's outflow, per Redfin's analysis of Census Bureau migration data; and (2) when "hardest-hit" is defined more broadly — by cumulative disaster damage or by disaster-declaration frequency across the full universe of FEMA-declared counties — the aggregate picture is flat to modestly negative, not a mass exodus. Our own query of IRS migration records against FEMA/NOAA damage data found the 308 counties with the highest cumulative storm-damage-per-capita (2012-2021) actually gained 610,711 people on net (+1.9% of baseline population), because that group is dominated by large, economically dynamic metros like Harris County, TX (Houston) that keep growing despite disaster losses. The exodus the question is pointing at is concentrated in roughly 40% of high-flood-risk counties — mostly expensive coastal urban cores (Miami-Dade, Harris County, Brooklyn) — while cheaper flood-risk counties in Florida, Texas, and the Carolinas are still gaining residents.

Step 1 — Checking the premise

The premise ("repeated disaster damage is driving mass depopulation of at-risk counties") is partially true and directionally accelerating, per a June 2026 Redfin analysis of Census Bureau domestic-migration data matched to First Street climate-risk scores. High-flood-risk counties — the top decile of the 3,103 counties analyzed, ranked by the share of homes facing major/severe/extreme flood risk (23.7%–99.1% of homes) — lost a net 63,357 residents in the year ending mid-2025, up from a net loss of 34,099 the year before (2024 was the first net-outflow year in five). Meanwhile low-risk counties gained a net 69,857 residents, their biggest gain since 2018. Academic literature backs a causal (not just correlational) link: Ton et al. (2024, Natural Hazards) find hurricanes, floods, and severe storms are all associated with measurably larger out-migration from the origin county in a gravity-model analysis of IRS migration flows, with hurricanes showing the largest effect; Boustan et al. (2020) find disasters causing 25+ fatalities produce about 1.5 percentage points of additional net out-migration.

Step 2 — How large is the exodus from the hardest-hit places?

Among counties defined narrowly as "high flood risk" (Redfin/First Street), the loss is real but concentrated, not universal. Of the 310 high-flood-risk counties Redfin analyzed, only 128 (41%) actually saw net outflow in 2025; the other 182 gained residents. The net national figure of -63,357 is driven overwhelmingly by a small number of large, expensive coastal metros: Miami-Dade County, FL alone lost 72,254 residents (its largest outflow on record) — more than the net national total for the whole high-risk group. Harris County, TX (Houston) lost 43,377 and Kings County, NY (Brooklyn) lost 38,847. Together, Miami-Dade, Harris, and Kings account for roughly 78% of the total gross outflow among the 128 losing counties. By contrast, more affordable high-flood-risk counties — St. Johns County, FL (+12,549), Fort Bend County, TX (+10,406), Lee County, FL (+8,603) — are still gaining population despite the same or worse flood exposure; every one of the ten biggest-gaining high-risk counties has a median home list price under $500K, versus roughly $1 million or more in three of the ten biggest-losing counties (Kings, Marin, Monroe). The pattern reads less like flight from disaster risk per se and more like flight from the combination of disaster risk AND high cost/insurance burden — cheaper flood-prone places are still absorbing residents.

When "hardest-hit" is defined by actual cumulative disaster damage or declaration frequency across the whole country — not just the flood-risk-scored subset — the aggregate migration signal disappears or reverses. We queried AskAmerica's IRS SOI county-to-county migration flows (fiscal.county_migration_flows, 2012-2021) against two independent "hardest-hit" definitions built from FEMA/NOAA data already in the warehouse: (a) the 308 counties (top decile of 3,081 with usable data) with the highest cumulative NOAA storm property damage per capita, 2012-2021 — this group, baseline population 32.8 million, gained a net 610,711 residents (+1.9%) over the decade, because it is dominated by damage-heavy but fast-growing metros (Galveston/Harris/Montgomery Counties, TX top the per-capita damage list from Hurricane Harvey); and (b) the 295 counties (top decile of 2,979) with the most FEMA disaster declarations 2012-2021 — dominated by Louisiana's coastal parishes, which get declared for nearly every Gulf storm — this group, baseline population 52.9 million, lost a net 107,481 residents (-0.2%), essentially flat. Neither of these broader, damage/frequency-based cuts shows anything resembling "mass depopulation."

Bottom line on magnitude: the real, accelerating exodus is on the order of 30,000-70,000 net domestic movers per year nationally, concentrated in a handful of expensive, high-flood-risk urban counties (Miami-Dade losing roughly 70,000+ residents a year is by far the largest single component). It is not a broad-based flight from disaster-prone America — most disaster-declared and disaster-damaged counties, including many repeatedly hit ones, are holding steady or still growing, because economic opportunity and affordability continue to outweigh climate risk for most movers.

Methodology and caveats

Every query behind this report

14 warehouse calls ran in this session, in order. Each is reproducible against the same snapshot.

query — 1607 ms
SELECT county_fips, COUNT(DISTINCT disaster_number) AS disaster_count
FROM disasters.disaster_declarations
WHERE ia_program_declared = true AND "year" BETWEEN '2012' AND '2022' AND county_fips IS NOT NULL
GROUP BY county_fips
ORDER BY disaster_count DESC
LIMIT 20
query — 1 rows — 1621 ms
SELECT COUNT(DISTINCT county_fips) AS n_counties, AVG(cnt) AS avg_disasters
FROM (
  SELECT county_fips, COUNT(DISTINCT disaster_number) AS cnt
  FROM disasters.disaster_declarations
  WHERE ia_program_declared = true AND "year" BETWEEN '2012' AND '2022' AND county_fips IS NOT NULL
  GROUP BY county_fips
) t
query — 17 rows — 2154 ms
SELECT "year", ia_program_declared, COUNT(*) FROM disasters.disaster_declarations GROUP BY "year", ia_program_declared ORDER BY "year" LIMIT 30
query — 25 rows — 2245 ms
SELECT county_fips, COUNT(DISTINCT disaster_number) AS disaster_count
FROM disasters.disaster_declarations
WHERE "year" BETWEEN '2012' AND '2022' AND county_fips IS NOT NULL
GROUP BY county_fips
ORDER BY disaster_count DESC
FETCH FIRST 25 ROWS ONLY
query — 1 rows — 2722 ms
WITH cnt AS (
  SELECT county_fips, COUNT(DISTINCT disaster_number) AS disaster_count
  FROM disasters.disaster_declarations
  WHERE "year" BETWEEN '2012' AND '2022' AND county_fips IS NOT NULL
  GROUP BY county_fips
)
SELECT COUNT(*) AS n_counties, AVG(disaster_count) AS avg_count, MAX(disaster_count) AS max_count, MIN(disaster_count) AS min_count
FROM cnt
query — 1 rows — 16759 ms
WITH cnt AS (
  SELECT county_fips, COUNT(DISTINCT disaster_number) AS disaster_count
  FROM disasters.disaster_declarations
  WHERE "year" BETWEEN '2012' AND '2022' AND county_fips IS NOT NULL
  GROUP BY county_fips
),
ranked AS (
  SELECT county_fips, disaster_count,
         ROW_NUMBER() OVER (ORDER BY disaster_count DESC) AS rn
  FROM cnt
),
hardest AS (
  SELECT county_fips, disaster_count FROM ranked WHERE rn <= 328
)
SELECT 
  (SELECT COALESCE(SUM(num_individuals),0) FROM fiscal.county_migration_flows m JOIN hardest h ON m.dest_county_fips = h.county_fips WHERE m."year" BETWEEN '2012' AND '2022') AS inflow_hardest,
  (SELECT COALESCE(SUM(num_individuals),0) FROM fiscal.county_migration_flows m JOIN hardest h ON m.origin_county_fips = h.county_fips WHERE m."year" BETWEEN '2012' AND '2022') AS outflow_hardest,
  (SELECT COUNT(*) FROM hardest) AS n_hardest
query — 10 rows — 791 ms
SELECT incident_type, COUNT(*) FROM disasters.disaster_declarations WHERE "year"='2020' GROUP BY incident_type ORDER BY 2 DESC FETCH FIRST 10 ROWS ONLY
query — 20 rows — 3455 ms
SELECT county_fips, COUNT(DISTINCT disaster_number) AS disaster_count
FROM disasters.disaster_declarations
WHERE "year" BETWEEN '2012' AND '2022' AND county_fips IS NOT NULL
  AND incident_type NOT IN ('Biological','Chemical','Terrorist')
GROUP BY county_fips
ORDER BY disaster_count DESC
FETCH FIRST 20 ROWS ONLY
query — 1 rows — 2736 ms
SELECT COUNT(*) AS n_counties FROM (
SELECT county_fips
FROM disasters.disaster_declarations
WHERE "year" BETWEEN '2012' AND '2022' AND county_fips IS NOT NULL
  AND incident_type NOT IN ('Biological','Chemical','Terrorist')
GROUP BY county_fips) t
query — 30 rows — 9222 ms
WITH dmg AS (
  SELECT county_fips, SUM(total_property_damage) AS total_damage
  FROM disasters.disasters_storm_impact_by_county
  WHERE "year" BETWEEN '2012' AND '2021' AND county_fips IS NOT NULL
  GROUP BY county_fips
),
pop AS (
  SELECT county_fips, MAX(total_population) AS population
  FROM census.acs_population
  WHERE "year" = '2012' 
  GROUP BY county_fips
)
SELECT d.county_fips, d.total_damage, p.population, d.total_damage/NULLIF(p.population,0) AS damage_per_capita
FROM dmg d JOIN pop p ON d.county_fips = p.county_fips
WHERE p.population > 1000
ORDER BY damage_per_capita DESC
FETCH FIRST 30 ROWS ONLY
query — 1 rows — 4972 ms
WITH dmg AS (
  SELECT county_fips, SUM(total_property_damage) AS total_damage
  FROM disasters.disasters_storm_impact_by_county
  WHERE "year" BETWEEN '2012' AND '2021' AND county_fips IS NOT NULL
  GROUP BY county_fips
),
pop AS (
  SELECT county_fips, MAX(total_population) AS population
  FROM census.acs_population
  WHERE "year" = '2012' 
  GROUP BY county_fips
)
SELECT COUNT(*) AS n
FROM dmg d JOIN pop p ON d.county_fips = p.county_fips
WHERE p.population > 1000
query — 1 rows — 53462 ms
WITH dmg AS (
  SELECT county_fips, SUM(total_property_damage) AS total_damage
  FROM disasters.disasters_storm_impact_by_county
  WHERE "year" BETWEEN '2012' AND '2021' AND county_fips IS NOT NULL
  GROUP BY county_fips
),
pop AS (
  SELECT county_fips, MAX(total_population) AS population
  FROM census.acs_population
  WHERE "year" = '2012' 
  GROUP BY county_fips
),
joined AS (
  SELECT d.county_fips, d.total_damage, p.population, d.total_damage/NULLIF(p.population,0) AS damage_per_capita
  FROM dmg d JOIN pop p ON d.county_fips = p.county_fips
  WHERE p.population > 1000
),
ranked AS (
  SELECT county_fips, population, damage_per_capita,
         ROW_NUMBER() OVER (ORDER BY damage_per_capita DESC) AS rn,
         COUNT(*) OVER () AS n_total
  FROM joined
),
hardest AS (
  SELECT county_fips, population FROM ranked WHERE rn <= (SELECT CAST(n_total*0.1 AS INT) FROM ranked LIMIT 1)
)
SELECT 
  (SELECT COUNT(*) FROM hardest) AS n_hardest,
  (SELECT SUM(population) FROM hardest) AS hardest_baseline_pop,
  (SELECT COALESCE(SUM(num_individuals),0) FROM fiscal.county_migration_flows m JOIN hardest h ON m.dest_county_fips = h.county_fips WHERE m."year" BETWEEN '2012' AND '2021') AS inflow_hardest,
  (SELECT COALESCE(SUM(num_individuals),0) FROM fiscal.county_migration_flows m JOIN hardest h ON m.origin_county_fips = h.county_fips WHERE m."year" BETWEEN '2012' AND '2021') AS outflow_hardest
query — 1 rows — 47880 ms
WITH cnt AS (
  SELECT county_fips, COUNT(DISTINCT disaster_number) AS disaster_count
  FROM disasters.disaster_declarations
  WHERE "year" BETWEEN '2012' AND '2021' AND county_fips IS NOT NULL
    AND incident_type NOT IN ('Biological','Chemical','Terrorist')
  GROUP BY county_fips
),
ranked AS (
  SELECT county_fips, disaster_count, ROW_NUMBER() OVER (ORDER BY disaster_count DESC) AS rn, COUNT(*) OVER () AS n_total
  FROM cnt
),
hardest AS (
  SELECT county_fips FROM ranked WHERE rn <= (SELECT CAST(n_total*0.1 AS INT) FROM ranked FETCH FIRST 1 ROWS ONLY)
),
pop AS (
  SELECT county_fips, MAX(total_population) AS population
  FROM census.acs_population WHERE "year"='2012' GROUP BY county_fips
)
SELECT 
  (SELECT COUNT(*) FROM hardest) AS n_hardest,
  (SELECT SUM(population) FROM pop p JOIN hardest h ON p.county_fips=h.county_fips) AS baseline_pop,
  (SELECT COALESCE(SUM(num_individuals),0) FROM fiscal.county_migration_flows m JOIN hardest h ON m.dest_county_fips = h.county_fips WHERE m."year" BETWEEN '2012' AND '2021') AS inflow,
  (SELECT COALESCE(SUM(num_individuals),0) FROM fiscal.county_migration_flows m JOIN hardest h ON m.origin_county_fips = h.county_fips WHERE m."year" BETWEEN '2012' AND '2021') AS outflow
query — 2 rows — 4017 ms
SELECT incident_type, COUNT(*) FROM disasters.disaster_declarations WHERE "year" BETWEEN '2012' AND '2021' AND incident_type IN ('Chemical','Terrorist') GROUP BY incident_type

Sources

  1. Redfin: Flood-Prone Parts of America Are Losing Residents at Nearly Twice Last Year's Rate — Published June 24, 2026; Census Bureau domestic migration + First Street risk scores
  2. Ton, de Moel, de Bruijn, Reimann, Botzen, Aerts (2024). Economic damage from natural hazards and internal migration in the United States. Natural Hazards. — Gravity-model analysis of IRS county migration flows vs. hazard damage
  3. AskAmerica: FEMA disaster declarations by county, damage-per-capita ranking
    Show SQL
    WITH dmg AS (SELECT county_fips, SUM(total_property_damage) AS total_damage FROM disasters.disasters_storm_impact_by_county WHERE "year" BETWEEN '2012' AND '2021' AND county_fips IS NOT NULL GROUP BY county_fips), pop AS (SELECT county_fips, MAX(total_population) AS population FROM census.acs_population WHERE "year"='2012' GROUP BY county_fips) SELECT d.county_fips, d.total_damage, p.population, d.total_damage/NULLIF(p.population,0) AS damage_per_capita FROM dmg d JOIN pop p ON d.county_fips=p.county_fips WHERE p.population>1000 ORDER BY damage_per_capita DESC
  4. AskAmerica: Net IRS SOI migration for top-decile counties by storm damage per capita, 2012-2021 (+610,711)
    Show SQL
    Inflow minus outflow from fiscal.county_migration_flows joined to the top-decile-by-damage-per-capita CTE, dest_county_fips vs origin_county_fips, year BETWEEN 2012 AND 2021
  5. AskAmerica: Net IRS SOI migration for top-decile counties by FEMA disaster-declaration frequency excl. Biological/Chemical/Terrorist, 2012-2021 (-107,481)
    Show SQL
    WITH cnt AS (SELECT county_fips, COUNT(DISTINCT disaster_number) AS disaster_count FROM disasters.disaster_declarations WHERE "year" BETWEEN '2012' AND '2021' AND county_fips IS NOT NULL AND incident_type NOT IN ('Biological','Chemical','Terrorist') GROUP BY county_fips) SELECT county_fips, disaster_count FROM cnt ORDER BY disaster_count DESC