Education and Schools
Why schools are an urban topic
In most of the United States, your address decides your public school. So when families choose a home, they also choose a school. That ties school quality to house prices, and it ties school funding to where people live.
What parents pay for schools
If good schools are worth something, homes in good school zones should cost more. The problem is that good school zones are also nicer in other ways: safer, wealthier, closer to parks. A simple comparison mixes all of these.
Sandra Black (1999) found a clever fix. She compared homes on opposite sides of a school attendance boundary. Homes a block apart share the same neighborhood, but their children go to different schools. Any price gap right at the boundary reflects the schools. She found that a 5% increase in test scores raised house prices by about 2.5%.
This is a regression discontinuity: look only at homes close to the line, where everything but the school is the same.
Does money matter?
Schools in rich towns often spend more, because they collect more property tax. For years, economists debated whether more spending actually helps students.
Newer evidence says it does. Jackson, Johnson and Persico (2016) studied court-ordered reforms that sent more money to poor school districts. Children who got more spending finished more school and earned more as adults. The effects were largest for children from low-income families.
School choice
Charter schools, vouchers, and open enrollment let some families pick a school without moving. This weakens the link between house prices and schools. It can also change who sorts where, since families no longer have to buy into a district to reach its schools.
#| standalone: true
#| viewerHeight: 620
library(shiny)
ui <- fluidPage(
tags$head(tags$style(HTML("
.info-box {
background: #eaf2f8; border-radius: 6px; padding: 14px;
margin-top: 12px; font-size: 13px; line-height: 1.8;
}
.info-box b { color: #2c3e50; }
"))),
sidebarLayout(
sidebarPanel(
width = 3,
sliderInput("school", "True school premium (% of price):",
min = 0, max = 10, value = 3, step = 0.5),
sliderInput("trend", "How much prices rise per mile to the right, without the school (%):",
min = 0, max = 20, value = 10, step = 1),
sliderInput("bw", "Boundary window (miles each side):",
min = 0.05, max = 1, value = 0.10, step = 0.05),
actionButton("go", "New sample", class = "btn-primary", width = "100%"),
uiOutput("info")
),
mainPanel(
width = 9,
plotOutput("plot", height = "480px")
)
)
)
server <- function(input, output, session) {
base <- 500 # $ thousands
homes <- reactive({
input$go
n <- 3000
x <- runif(n, -1, 1) # miles from the boundary
noise <- rnorm(n, 0, 0.04)
data.frame(x = x, noise = noise)
})
est <- reactive({
h <- homes()
right <- h$x > 0
logp <- log(base) + (input$trend / 100) * h$x +
(input$school / 100) * right + h$noise
price <- exp(logp)
naive <- mean(logp[right]) - mean(logp[!right])
near <- abs(h$x) <= input$bw
bnd <- mean(logp[right & near]) - mean(logp[!right & near])
list(x = h$x, price = price, right = right, near = near,
naive = 100 * naive, bnd = 100 * bnd, n_near = sum(near))
})
output$plot <- renderPlot({
e <- est()
par(mar = c(4.5, 4.5, 3, 1))
plot(e$x, e$price, pch = 16, cex = 0.5,
col = ifelse(e$near, ifelse(e$right, "#e67e22", "#2980b9"), "#d5d8dc"),
xlab = "Miles from the attendance boundary (right side has the better school)",
ylab = "House price ($ thousands)", main = "House prices across a school boundary")
rect(-input$bw, par("usr")[3], input$bw, par("usr")[4],
col = adjustcolor("#f39c12", 0.08), border = NA)
abline(v = 0, lwd = 2, col = "#2c3e50")
l <- e$near & !e$right; r <- e$near & e$right
segments(-input$bw, mean(e$price[l]), 0, mean(e$price[l]), lwd = 4, col = "#2980b9")
segments(0, mean(e$price[r]), input$bw, mean(e$price[r]), lwd = 4, col = "#e67e22")
legend("topleft", bty = "n", cex = 0.85,
legend = c("Near the line, worse school", "Near the line, better school",
"Outside the window", "Average near the line"),
col = c("#2980b9", "#e67e22", "#d5d8dc", "#2c3e50"),
pch = c(16, 16, 16, NA), lwd = c(NA, NA, NA, 4))
})
output$info <- renderUI({
e <- est()
tags$div(class = "info-box",
HTML(paste0(
"<b>True school premium:</b> ", sprintf("%.1f", input$school), "%<br>",
"<b>Naive estimate (all homes):</b> ", sprintf("%.1f", e$naive), "%<br>",
"<b>Boundary estimate:</b> ", sprintf("%.1f", e$bnd), "%<br>",
"<b>Homes in the window:</b> ", e$n_near
))
)
})
}
shinyApp(ui, server)
Things to try
- Start with the defaults. The naive estimate is much bigger than the true premium. It credits the school for the whole nicer area.
- Set “how much nicer” to 0. Now both estimates are close to the truth. The naive comparison only fails when the two sides differ in other ways.
- Widen the window to 1 mile. The boundary estimate drifts up toward the naive one. A wide window lets neighborhood differences back in.
- Shrink the window to 0.05 miles. The estimate is close to the truth on average, but it jumps around more when you press New sample. Fewer homes means more noise.
Who pays for schools?
US public schools get close to half their money from local sources, mostly property taxes. The rest comes mainly from the state, with a small federal share. Districts with expensive homes can raise a lot of money with a low tax rate. Districts with cheap homes cannot.
Starting in the 1970s, courts in many states ruled that this was unfair. States then sent more money to poorer districts. These school finance reforms are what Jackson, Johnson and Persico used to measure the effect of spending. A 2024 review of many studies by Jackson and Mackevicius finds that more spending raises test scores and college-going on average.
Connections
- Tiebout Sorting: families choose towns partly for their schools, and the property tax pays for them.
- Hedonic Pricing: school quality is one of the attributes priced into a home.
- Segregation and the Schelling Model: sorting by school can deepen segregation by income and race.
Did you know?
- Most US public school students attend the school assigned to their home address.
- In Serrano v. Priest (1971), the California Supreme Court ruled that funding schools mainly by local property taxes was unfair to students in poor districts. It was one of the first school finance cases.
- Real estate listings often name the school zone in the first line. Agents know buyers pay for it.
Key papers
- Black, S. E. (1999). Do Better Schools Matter? Parental Valuation of Elementary Education. Quarterly Journal of Economics 114(2). School quality at attendance-zone boundaries.
- Bayer, P., Ferreira, F. and McMillan, R. (2007). A Unified Framework for Measuring Preferences for Schools and Neighborhoods. Journal of Political Economy 115(4). What families pay for schools vs neighbors.
- Jackson, C. K., Johnson, R. C. and Persico, C. (2016). The Effects of School Spending on Educational and Economic Outcomes: Evidence from School Finance Reforms. Quarterly Journal of Economics 131(1). More spending, more schooling and higher earnings.
- Jackson, C. K. and Mackevicius, C. L. (2024). What Impacts Can We Expect from School Spending Policy? Evidence from Evaluations in the United States. American Economic Journal: Applied Economics 16(1). Spending raises test scores and college-going on average.