The Great Migration Slowdown Continues

Americans are known for our willingness to move for opportunity, but fewer than 1 in 10 Americans moved last year. That estimate is the lowest moving rate since 1947, when we started measuring domestic mobility. The CPS data are freely available, so I pulled together a few graphs to get a sense of the pattern.

It’s not easy to put a value judgement on this decline. Some people are probably stuck, but others might be “rooted”, a term the geographer Richard Florida uses to describe There are also neutral reasons for the decline: an aging population, for example, means that more people are reaching ages at which they’re less likely to move.

But there are good reasons to believe that the decline in interstate mobility might reflect a decline not in people’s desire to move but in their capability to make the need to move into a reality. David Schleicher, a law professor at Yale, points out that occupational licensing differences between states and location-based eligibility standards for benefits can both exacerbate the cost of a move. A teacher who moves from one district to another can lose about half the net pension wealth they’d have at the end of their career if they stayed in place. The costs of interstate “stuckness” are potentially big for society, too – the economists Tony Hsieh and Enrico Moretti argue that Declining migration, they argue, is a key driver of regional divergence.

Mobility has declined at every spatial distance, though – and in the last five years, interstate and intercounty mobility have largely stabilized. (Also worth nothing: interstate mobility hasn’t declined as much as we think, because there were some data imputation issues.) The long-term continuous slowdown that we’ve been talking about is really a decline in local moves:

Local moves have, historically, had very different drivers than do long-distance moves. A long-distance move is more likely to be about a job, while a local move tends to reflect a change in housing. Peter Rossi’s classic 1955 paper shows that, within metros, households move when their housing units no longer meet their space needs and their income enables them to move to a place that does meet their needs. Households move, most of the time, because a life course event – a birth, a death, a divorce – changes their need for space. An urban econ lens reminds us to think about commutes: when people choose where to live in a city, you can explain a lot about the residences they choose based on the tradeoff between commuting distance and space (with the important historical caveat that these relationships break when there’s redlining or other forms of housing discrimination).

The CPS data include some broad information on causes. What I’ve constructed is a graph of the overall number of moves with each explanation, as a fraction of the total population that could move. You see that the biggest historical driver of moves – and the one that has seen a fairly drastic decline – is the search for “better” housing. There’s also a decline in the rate of moves for new jobs, though that drop-off seems to stabilize after the recession; moving for homeownership similarly drops off precipitously in advance of the recession and then flattens out; and there’s an interesting drop-off in moving for health from 2010 to 2015 that lines up nicely with the Affordable Care Act passage and the Medicaid Expansions – though the presence of a similar pattern in moves to attend college and “other” unstated reasons suggests to me that the pattern might be spurious.

What does all this tell us? There’s a lot more to unpack here, and it would be well worth your time to dig into the CPS microdata or the IRS migration estimates for spatial and social patterning. Still, it seems as though the focus on interstate migration obfuscates the role for local moves.

.

# load data and clean headers
reason.raw <- read_xls("data/cpsreason.xls", skip = 6)
colnames(reason.raw) <- c("period", "totalmovers", "family.maritalstatus", "family.ownhousehold", "family.familyother",
                          "job.new", "job.searchorlost", "job.commute", "job.retired", "job.jobother",
                          "period2", "house.own", "house.better", "house.nbdlesscrime", "house.cheaper", "house.eviction", 
                          "house.houseother", "other.college", "other.climate", "other.health", "other.disaster", "other.otherother")

# clean the cps data
reason.clean <- reason.raw %>%
        # clean up year column
        separate(period, by = "-| ", into = c("startyear", "endyear")) %>%
        mutate(startyear = as.numeric(startyear)) %>%
        # identify count versus percent rows
        mutate(type = ifelse(totalmovers == 100, "percent", "count")) %>%
        # keep only first observation of duplicated rows
        group_by(startyear, type) %>% slice(1) %>% ungroup() %>%
        # drop extra rows
        filter(startyear %in% c(1947:2018)) %>%
        dplyr::select(-period2) %>%
        gather(key = reason, value = value, family.maritalstatus:other.otherother) %>%
        mutate(value = as.numeric(value)) %>%
        separate(reason, by = "[.]", into = c("category", "reason")) %>%
        left_join(mob.clean[,c("startyear", "total", "type")], by = c("startyear", "type")) 
 
# make the raw plot       
ggplot(reason.clean[reason.clean$type=="count",], 
       aes(x = startyear, y = value/total, col = category, group = reason)) + 
        geom_line() + 
        xlab("Year") + ylab("Moving Rate") + theme_minimal() + scale_color_manual(values = c("grey", "grey", "grey", "grey")) + 
        facet_wrap(~category)

write.csv(reason.clean[reason.clean$type=="count",], 
           "data/reason.csv")
  • You can find the code for this article on my github.
Avatar
Madeleine I. G. Daepp
Senior Researcher

Senior Researcher, Microsoft Research Urban Innovation Initiative