Rural counties that got federal broadband money gained no measurably more broadband access than those that got none, 2017-2023
Nonmetro-county diff-in-differences, ACS 5-year broadband-household share vs. CAF-II/ReConnect funding, 2017 to 2023
Summary
At the county level, rural counties that received federal broadband subsidy money (FCC Connect America Fund Phase II, or USDA ReConnect) gained broadband-household coverage at essentially the same rate as rural counties that received neither — both groups rose from about 66.6-66.7% of households with broadband in 2017 to about 82.0-82.3% in 2023, a roughly 15.5-15.7 percentage-point gain either way. A difference-in-differences regression puts the funded group's extra gain at +0.43 percentage points (95% CI roughly -0.6 to +1.5 pp), not statistically distinguishable from zero (p=0.41), and this null holds up under a state-by-state leave-one-out check (coefficient stays in a narrow 0.22-0.71 pp band no matter which state is dropped; never flips sign or crosses significance). Independent 2024 research on the same CAF program helps explain why: audits of CAF-II-funded addresses found only about 55% were actually serviceable and only 33% met the speed/compliance terms the subsidy was paid for — a substantial share of the 'funded' population never really got the promised service, which would blunt any county-level improvement the subsidy should otherwise show.
Data and method
Outcome: the ACS 5-year share of households with a broadband subscription (census.acs_internet, Census table B28002), at county grain, for 2017 and 2023 — the earliest and latest years loaded (ACS publishes on a roughly 2-year lag, so 2024-2026 do not exist yet upstream).
Population: nonmetro (rural) counties only, per USDA's 2023-vintage Rural-Urban Continuum Code (geo.rural_urban_continuum), n=1,969 counties with matched ACS data in both years.
Treatment: a county is 'funded' if it appears in EITHER (a) fiscal.broadband_caf_deployment_locations — USAC's own record of every address FCC Connect America Fund Phase II carriers certified as built out (deployment reported mostly 2015-2018, funding period ran through 2021), or (b) fiscal.broadband_reconnect_awards — USDA's award-level ReConnect grants (county-grain recipient location). 1,257 of 1,969 rural counties (64%) had at least one such record; 712 had neither, forming the comparison group. (RDOF and ACAM/high-cost carrier disbursements exist in this warehouse only at carrier grain, not county grain, so they could not be added to the treatment definition — see caveats below.)
Design: a standard two-period diff-in-differences (outcome ~ treatment + post + treatment×post), run via the connector's diff_in_diff tool, with treatment×post as the estimated average effect of funding on the treated group's broadband-share change.
Result
| Group | 2017 avg. broadband share | 2023 avg. broadband share | Change |
|---|---|---|---|
| Funded rural counties (n=1,257) | 66.59% | 82.30% | +15.71 pp |
| Unfunded rural counties (n=712) | 66.72% | 82.00% | +15.28 pp |
DiD estimate (the gap between those two changes): +0.43 percentage points, std. error 0.53 pp, p=0.41 — well within noise. Restricting the treatment definition to CAF-II alone (dropping ReConnect, which mostly started construction in 2022-2023 and would show almost no effect by the 2023 5-year ACS window anyway) gives essentially the same picture: 66.57%→82.28% (funded) vs. 66.75%→82.05% (unfunded).
Robustness: a state-by-state leave-one-out check (sensitivity_analysis) re-ran the regression 49 times, once per state omitted. The treatment×post coefficient never left a 0.22-0.71 pp range, never flipped sign, and never crossed p=0.05 in either direction — no single state is driving the null.
Why the gap might be smaller than expected — corroborating research
A 2024 peer-reviewed study by UC Santa Barbara, UC Berkeley, and Ookla researchers (presented at ACM SIGCOMM 2024) independently audited the same CAF program using large-scale address-level broadband-plan queries against the ISPs' own FCC-certified service claims. They found only a 55% serviceability rate — barely more than half of CAF-certified addresses were actually receiving service from the funded carrier — and only a 33% compliance rate with the required minimum speeds. Their conclusion: 'the CAF program has largely failed to achieve its intended goal, leaving many targeted rural communities with inadequate or no broadband connectivity.' That gap between certified deployment and delivered service is a plausible mechanism for why funded counties show no measurable edge over unfunded ones in the household survey data: the subsidy paid for construction the regulator counted as complete, but a large share of it did not translate into working household subscriptions.
Caveats
- Not a random assignment. Counties that got CAF-II/ReConnect money were the ones the FCC/USDA already identified as underserved; unfunded rural counties may have already had better incumbent service (e.g. cable, DSL upgrades, or state-funded builds outside this warehouse), which would bias the comparison AGAINST finding a funding effect even if the subsidies genuinely helped at the margin.
- Program-timing mismatch. Most ReConnect awards in this data (59 of 99 nationally) have performance start dates in 2023, meaning most of the buildout is not yet reflected in a 2023 5-year ACS estimate (which averages 2019-2023). CAF-II is the more timing-appropriate program for this window since its build period ran 2015-2021.
- Coverage gap: RDOF, ACAM, and BEAD are not testable here at county grain. fiscal.broadband_high_cost_disbursements carries RDOF/ACAM/CAF-BLS dollars only at carrier×month grain, with no address or county location; fiscal.broadband_bead_state_allocations is state-grain only. This analysis can only speak to CAF-II and ReConnect, not the full universe of federal rural broadband programs.
- ACS margin of error. County-level 5-year ACS broadband estimates carry real sampling error, especially in small rural counties; a handful of percentage points of noise per county is expected and is part of why a 0.43 pp aggregate difference is not distinguishable from zero.
What This Report Does Not Answer
- Cover the universe of 'federal money' (all major programs: CAF-II, RDOF, ACAM, ReConnect, BEAD): Only CAF-II and ReConnect could be tested at county grain; RDOF/ACAM exist only at carrier grain and BEAD only at state grain in this warehouse, so they are not part of the treatment definition. Disclosed explicitly in the Caveats section.
Every query behind this report
9 warehouse calls ran in this session, in order. Each is reproducible against the same snapshot.
query — 1 rows — 1454 ms
SELECT COUNT(DISTINCT county_fips) AS n_counties, MIN(start_date) AS min_start, MAX(start_date) AS max_start, SUM(award_amount) AS total_amt FROM fiscal.broadband_reconnect_awards WHERE county_fips IS NOT NULLquery — 4 rows — 2764 ms
WITH treated AS (
SELECT DISTINCT county_fips FROM fiscal.broadband_reconnect_awards
WHERE county_fips IS NOT NULL AND start_date <= '2021-12-31'
),
rural AS (
SELECT county_fips FROM geo.rural_urban_continuum WHERE metro_nonmetro = 'Nonmetro'
),
bb AS (
SELECT county_fips, "year",
CAST(with_broadband AS DOUBLE)/NULLIF(total_households,0) AS bb_share
FROM census.acs_internet
WHERE geography = 'county' AND "year" IN ('2017','2023')
)
SELECT bb."year", CASE WHEN t.county_fips IS NOT NULL THEN 1 ELSE 0 END AS treated,
COUNT(*) AS n_counties, AVG(bb.bb_share) AS avg_broadband_share
FROM bb
JOIN rural r ON r.county_fips = bb.county_fips
LEFT JOIN treated t ON t.county_fips = bb.county_fips
GROUP BY bb."year", CASE WHEN t.county_fips IS NOT NULL THEN 1 ELSE 0 END
ORDER BY treated, bb."year"
query — 1 rows — 1856 ms
WITH treated AS (
SELECT county_fips, MIN(start_date) AS first_start FROM fiscal.broadband_reconnect_awards
WHERE county_fips IS NOT NULL GROUP BY county_fips
),
rural AS (SELECT county_fips FROM geo.rural_urban_continuum WHERE metro_nonmetro = 'Nonmetro')
SELECT COUNT(*) AS n_treated_total,
SUM(CASE WHEN r.county_fips IS NOT NULL THEN 1 ELSE 0 END) AS n_treated_rural,
MIN(t.first_start) AS earliest, MAX(t.first_start) AS latest
FROM treated t LEFT JOIN rural r ON r.county_fips = t.county_fips
query — 5 rows — 911 ms
WITH treated AS (
SELECT county_fips, MIN(start_date) AS first_start FROM fiscal.broadband_reconnect_awards
WHERE county_fips IS NOT NULL GROUP BY county_fips
)
SELECT SUBSTR(first_start,1,4) AS start_year, COUNT(*) FROM treated GROUP BY SUBSTR(first_start,1,4) ORDER BY 1
query — 1 rows — 4326 ms
SELECT COUNT(DISTINCT SUBSTR(census_block,1,5)) AS n_counties FROM fiscal.broadband_caf_deployment_locations WHERE census_block IS NOT NULL
query — 4 rows — 3765 ms
WITH caf_counties AS (
SELECT DISTINCT SUBSTR(census_block,1,5) AS county_fips
FROM fiscal.broadband_caf_deployment_locations
WHERE census_block IS NOT NULL
),
rural AS (
SELECT county_fips FROM geo.rural_urban_continuum WHERE metro_nonmetro = 'Nonmetro'
),
bb AS (
SELECT county_fips, "year",
CAST(with_broadband AS DOUBLE)/NULLIF(total_households,0) AS bb_share,
total_households
FROM census.acs_internet
WHERE geography = 'county' AND "year" IN ('2017','2023')
)
SELECT bb."year", CASE WHEN c.county_fips IS NOT NULL THEN 1 ELSE 0 END AS treated,
COUNT(*) AS n_counties,
AVG(bb.bb_share) AS avg_broadband_share,
SUM(bb.bb_share*bb.total_households)/SUM(bb.total_households) AS hh_weighted_share
FROM bb
JOIN rural r ON r.county_fips = bb.county_fips
LEFT JOIN caf_counties c ON c.county_fips = bb.county_fips
GROUP BY bb."year", CASE WHEN c.county_fips IS NOT NULL THEN 1 ELSE 0 END
ORDER BY treated, bb."year"
query — 4 rows — 4562 ms
WITH caf_counties AS (
SELECT DISTINCT SUBSTR(census_block,1,5) AS county_fips
FROM fiscal.broadband_caf_deployment_locations WHERE census_block IS NOT NULL
),
reconnect_counties AS (
SELECT DISTINCT county_fips FROM fiscal.broadband_reconnect_awards WHERE county_fips IS NOT NULL
),
treated_any AS (
SELECT county_fips FROM caf_counties
UNION
SELECT county_fips FROM reconnect_counties
),
rural AS (
SELECT county_fips FROM geo.rural_urban_continuum WHERE metro_nonmetro = 'Nonmetro'
),
bb AS (
SELECT county_fips, "year",
CAST(with_broadband AS DOUBLE)/NULLIF(total_households,0) AS bb_share
FROM census.acs_internet
WHERE geography = 'county' AND "year" IN ('2017','2023')
)
SELECT bb."year", CASE WHEN t.county_fips IS NOT NULL THEN 1 ELSE 0 END AS treated,
COUNT(*) AS n_counties, AVG(bb.bb_share) AS avg_broadband_share
FROM bb
JOIN rural r ON r.county_fips = bb.county_fips
LEFT JOIN treated_any t ON t.county_fips = bb.county_fips
GROUP BY bb."year", CASE WHEN t.county_fips IS NOT NULL THEN 1 ELSE 0 END
ORDER BY treated, bb."year"
diff_in_diff — 4588 ms
WITH caf_counties AS (
SELECT DISTINCT SUBSTR(census_block,1,5) AS county_fips
FROM fiscal.broadband_caf_deployment_locations WHERE census_block IS NOT NULL
),
reconnect_counties AS (
SELECT DISTINCT county_fips FROM fiscal.broadband_reconnect_awards WHERE county_fips IS NOT NULL
),
treated_any AS (
SELECT county_fips FROM caf_counties
UNION
SELECT county_fips FROM reconnect_counties
),
rural AS (
SELECT county_fips FROM geo.rural_urban_continuum WHERE metro_nonmetro = 'Nonmetro'
),
bb AS (
SELECT county_fips, "year",
CAST(with_broadband AS DOUBLE)/NULLIF(total_households,0) AS bb_share
FROM census.acs_internet
WHERE geography = 'county' AND "year" IN ('2017','2023')
)
SELECT bb.county_fips, bb."year",
CASE WHEN bb."year" = '2023' THEN 1 ELSE 0 END AS post,
CASE WHEN t.county_fips IS NOT NULL THEN 1 ELSE 0 END AS treatment,
bb.bb_share
FROM bb
JOIN rural r ON r.county_fips = bb.county_fips
LEFT JOIN treated_any t ON t.county_fips = bb.county_fips
WHERE bb.bb_share IS NOT NULL
sensitivity_analysis — 4908 ms
WITH caf_counties AS (
SELECT DISTINCT SUBSTR(census_block,1,5) AS county_fips
FROM fiscal.broadband_caf_deployment_locations WHERE census_block IS NOT NULL
),
reconnect_counties AS (
SELECT DISTINCT county_fips FROM fiscal.broadband_reconnect_awards WHERE county_fips IS NOT NULL
),
treated_any AS (
SELECT county_fips FROM caf_counties
UNION
SELECT county_fips FROM reconnect_counties
),
rural AS (
SELECT county_fips, state_fips FROM geo.rural_urban_continuum WHERE metro_nonmetro = 'Nonmetro'
),
bb AS (
SELECT county_fips, "year",
CAST(with_broadband AS DOUBLE)/NULLIF(total_households,0) AS bb_share
FROM census.acs_internet
WHERE geography = 'county' AND "year" IN ('2017','2023')
)
SELECT bb.county_fips, r.state_fips, bb."year",
CASE WHEN bb."year" = '2023' THEN 1 ELSE 0 END AS post,
CASE WHEN t.county_fips IS NOT NULL THEN 1 ELSE 0 END AS treatment,
(CASE WHEN bb."year"='2023' THEN 1 ELSE 0 END) * (CASE WHEN t.county_fips IS NOT NULL THEN 1 ELSE 0 END) AS treatment_x_post,
bb.bb_share
FROM bb
JOIN rural r ON r.county_fips = bb.county_fips
LEFT JOIN treated_any t ON t.county_fips = bb.county_fips
WHERE bb.bb_share IS NOT NULL
Sources
- ACS 5-Year broadband-household share by county, 2017 & 2023 (B28002)
Show SQL
SELECT county_fips, "year", with_broadband, total_households FROM census.acs_internet WHERE geography='county' AND "year" IN ('2017','2023') - FCC Connect America Fund Phase II deployment locations (USAC opendata, r59r-rpip)
Show SQL
SELECT DISTINCT SUBSTR(census_block,1,5) AS county_fips FROM fiscal.broadband_caf_deployment_locations WHERE census_block IS NOT NULL - USDA ReConnect award-level grants (USAspending API)
Show SQL
SELECT DISTINCT county_fips FROM fiscal.broadband_reconnect_awards WHERE county_fips IS NOT NULL - USDA ERS Rural-Urban Continuum Codes, 2023 vintage
Show SQL
SELECT county_fips FROM geo.rural_urban_continuum WHERE metro_nonmetro='Nonmetro' - Diff-in-differences estimate, treatment x post coefficient
Show tool call
diff_in_diff(outcome="bb_share", treatment="treatment", post="post") - State leave-one-out sensitivity check on the DiD coefficient
Show tool call
sensitivity_analysis(outcome="bb_share", predictors=["treatment","post","treatment_x_post"], group_col="state_fips", term="treatment_x_post") - Gupta, Belding et al., "An Audit of the FCC's Connect America Fund" (SIGCOMM 2024), via UCSB news — 55% serviceability, 33% compliance rate found in independent audit of CAF-II-certified addresses