In the counties hit hardest by branch closures since 2008, real small-business lending fell — not grew — even as guaranteed SBA lending partly filled the gap
FDIC Summary of Deposits + FFIEC CRA aggregate small-business lending + SBA 7(a)/504 approvals, county grain, 2009-2020/2024
Summary
Yes, with an important qualifier. In the U.S. counties that lost the largest share of their bank branches between 2009 and the 2020s — mostly small Rust Belt metros (Saginaw and Monroe, MI; Wayne and Madison, IN; Alamance and Randolph, NC; Muscogee, GA; several municipalities in Virginia and Puerto Rico) — inflation-adjusted, per-capita small-business lending from all CRA-reporting lenders fell about 13% between 2009 and 2020, while it grew about 32% over the same period in a comparison group of counties where branch networks expanded. A nationwide correlational test across 1,729 counties shows the same pattern: the more branches a county lost, the weaker its small-business lending growth. But the picture is not a simple void — federally guaranteed SBA 7(a)/504 lending, a much smaller channel, actually grew faster in the hardest-hit counties than elsewhere, partially offsetting the pullback from conventional lenders. This mirrors the gross-vs-net pattern found in the academic literature on branch closures: a real, persistent decline in local lending that other channels only partly heal.
What the published research says
Branch closures reducing local small-business credit is well established:
- A UC Berkeley study of branches closed after bank mergers found small-business lending in the affected census tract fell roughly 13% (net) / 19-22% (gross, before substitution by other lenders) and stayed depressed for 8+ years — Nguyen (2019), American Economic Journal: Applied Economics, "Are Credit Markets Still Local? Evidence from Bank Branch Closings". That paper uses merger-driven closures as a genuine quasi-experiment; the warehouse analysis below is cross-sectional and does not attempt to replicate that research design.
- A Federal Reserve Board study found that when 25% of branches within a 3-mile radius closed, small-business employment growth fell 2% within 3 years and 4% within 5 years; a full local wipeout cut growth 16% at 5 years — summarized in World Economic Forum.
- NCRC's tract-level study of 2008-2016 closures documented an unequal geographic pattern, with 82% of closures in urban areas but disproportionate harm in low-and-moderate-income and rural tracts — NCRC Branch Deserts Research Memo; a 2017-2020 update is at NCRC.
- A St. Louis Fed analysis found bank lending to small businesses declined 2019-2023 despite stable demand, with rural banking deserts seeing steeper declines than urban ones — see Fed Communities, "The financial frontier".
The published literature's own gross/net decomposition is the key nuance: the ~19-22% decline is the directly-affected lender's own pullback; roughly half of that gap is recovered as other banks and credit unions step in, leaving a net ~9-13% shortfall. That is consistent in direction with what the warehouse data below shows independently, with SBA-guaranteed lending as the visible substitute channel.
Step 1 — Where branches actually closed the most, 2009-2024
Using FDIC Summary of Deposits branch-office counts (counted by distinct FDIC office number, county grain, restricted to counties with at least 30 branches in 2009 to avoid noise from tiny markets), the counties with the steepest percentage branch decline from 2009 to 2024 are led by several Puerto Rico municipios (Bayamón, Ponce, Guaynabo, Caguas, Carolina — each down roughly 50-65%) and, on the mainland, small industrial metros: Madison County IN (-58%), Saginaw County MI (-49%), Wayne County IN (-51%), Monroe County MI (-48%), Muscogee County GA (-45%), Alamance County NC (-46%), and several independent cities in Virginia (Norfolk, Chesapeake, Charlottesville) each down roughly 45-52%.
Two exclusions applied to this ranking, both disclosed here: (a) Connecticut's counties were dropped entirely — the state replaced its counties with new planning-region FIPS codes around 2022, which would otherwise show every Connecticut county as a false 100% branch loss, an artifact of the code change rather than real closures; and (b) branch records with no county_fips (about 30-32% of all banking.sod rows, mostly foreign/territorial offices FDIC codes as having no resolvable US county) were excluded from every county-level count in this analysis, on both the branch and lending side. That share is large enough to note explicitly: it does not change which counties rank as the worst-hit (foreign branches are geographically unrelated to any of the counties studied), but it means the branch counts here undercount each institution's total network size, not just its county-level footprint.
A comparison group of counties with branch-count growth over the same window is concentrated in New England and fast-growing Sun Belt suburbs: Chittenden County VT (+38%), Schenectady County NY (+36%), Richmond County NY (+34%), Rockingham County NH (+29%), Collin and Denton Counties TX, Shelby County AL, and similar.
Step 2 — Testing whether lending actually shrank there
Using FFIEC's CRA aggregate small-business lending file (the broadest available measure — dollar volume of loans to businesses with revenue under $1M, summed across every CRA-reporting bank in a county, 2009 vs. 2020 — the longest common window the data supports), and adjusting for both inflation (2024 dollars) and population growth:
| Group | Real $/capita, 2009 | Real $/capita, 2020 | Change |
|---|---|---|---|
| 15 worst branch-loss counties | $413 | $358 | -13.3% |
| 14 branch-growth counties | $370 | $489 | +32.2% |
Extended nationwide (1,729 counties with ≥10 branches in 2009, matched to CRA lending in both years), the relationship holds as a correlation, not just an artifact of the two hand-picked groups: counties in the worst branch-loss quintile (average -31% branch count) saw nominal small-business loan-dollar growth of only 33% from 2009-2020, versus 56-86% in the less-affected quintiles. The bivariate correlation is weak (r=0.10, n=1,729) and the quintile trend is only marginally significant (p=0.094) — branch loss is one input among many to a county's lending trajectory, not a dominant one — but the direction is consistent with both the hand-picked comparison and the published literature. Two caveats on this specific nationwide cut: the underlying percent-change fields (branch_pct_chg, lending_pct_chg) are simple ratios of two point-in-time counts/dollar totals with no smoothing, so a county with an unusually small 2009 base can show an extreme, noisy percent change that carries outsized weight in the correlation and quintile means; and this nationwide cut is a plain cross-sectional correlation and dose-response test only — it does not isolate branch closures from the many other things that differ between growing and declining counties.
Step 3 — The partial offset: SBA-guaranteed lending
SBA 7(a)/504 loan approvals (a federally guaranteed but much smaller slice of small-business credit — roughly 15-20% of total CRA-reported dollar volume in these counties) moved in the opposite direction: real dollar volume grew 80% in the worst branch-loss counties from 2009-2012 to 2019-2022, versus 47% in the branch-growth counties, and loan count grew 26% in the branch-loss group while it fell 6% in the branch-growth group. This is consistent with SBA lending acting as a partial, policy-driven substitute for withdrawing conventional bank branches — the same gross-vs-net offset the academic literature describes, just visible here as two distinct lending channels moving in opposite directions rather than as one study's before/after adjustment. This is a descriptive contrast between two separately-computed trends, not a formal test of substitution.
Caveats
- Not causal. This is a cross-sectional/before-after comparison, not a natural experiment. Rust Belt counties that lost the most branches were often also losing population, manufacturing employment, and overall economic vitality over the same period — branch closures and weak loan demand plausibly share a common upstream cause (regional decline) rather than closures purely causing the lending shortfall. The literature above (especially Nguyen 2019, which uses merger-driven closures as a quasi-experiment) makes the causal case more rigorously than this cross-sectional data can.
- CRA aggregate data window is 2009-2020 — the longest span this table supports, but it does not reach the most recent branch-closure acceleration (2021-2024), which the SBA and branch-count series do cover.
- CRA data excludes lenders below the CRA reporting-asset threshold (roughly banks under $1.3B in assets are only voluntary reporters), so very small community banks' lending is undercounted in both periods equally, not a source of trend bias but a coverage limit worth naming.
- Records with no resolvable county (about 30-32% of banking.sod rows) were dropped from every branch count in this analysis — mostly foreign offices FDIC codes with no U.S. county, not a systematic loss specific to any state or region studied here.
- Puerto Rico's very large branch losses reflect the territory's banking-sector consolidation after its own fiscal crisis, a distinct dynamic from mainland Rust Belt closures; both are included in the "worst branch-loss" group but are not the same underlying story.
Every query behind this report
13 warehouse calls ran in this session, in order. Each is reproducible against the same snapshot.
query — 25 rows — 2168 ms
WITH b2009 AS (
SELECT county_fips, COUNT(DISTINCT uninum) AS branches_2009
FROM banking.sod WHERE year = '2009' AND county_fips IS NOT NULL
GROUP BY county_fips
), b2024 AS (
SELECT county_fips, COUNT(DISTINCT uninum) AS branches_2024
FROM banking.sod WHERE year = '2024' AND county_fips IS NOT NULL
GROUP BY county_fips
)
SELECT b2009.county_fips, branches_2009, COALESCE(branches_2024,0) AS branches_2024,
COALESCE(branches_2024,0) - branches_2009 AS abs_change,
ROUND(100.0*(COALESCE(branches_2024,0) - branches_2009)/branches_2009, 1) AS pct_change
FROM b2009
LEFT JOIN b2024 ON b2009.county_fips = b2024.county_fips
WHERE branches_2009 >= 20
ORDER BY pct_change ASC
LIMIT 25query — 20 rows — 1833 ms
WITH b2009 AS (
SELECT county_fips, MAX(state_abbr) AS state_abbr, COUNT(DISTINCT uninum) AS branches_2009
FROM banking.sod WHERE year = '2009' AND county_fips IS NOT NULL AND state_abbr <> 'CT'
GROUP BY county_fips
), b2024 AS (
SELECT county_fips, COUNT(DISTINCT uninum) AS branches_2024
FROM banking.sod WHERE year = '2024' AND county_fips IS NOT NULL AND state_abbr <> 'CT'
GROUP BY county_fips
)
SELECT b2009.county_fips, state_abbr, branches_2009, COALESCE(branches_2024,0) AS branches_2024,
COALESCE(branches_2024,0) - branches_2009 AS abs_change,
ROUND(100.0*(COALESCE(branches_2024,0) - branches_2009)/branches_2009, 1) AS pct_change
FROM b2009
LEFT JOIN b2024 ON b2009.county_fips = b2024.county_fips
WHERE branches_2009 >= 30
ORDER BY pct_change ASC
FETCH FIRST 20 ROWS ONLYquery — 17 rows — 1007 ms
SELECT county_name FROM geo.counties WHERE county_fips IN ('72097','47105','72031','18095','72061','18065','51840','72025','72113','26157','26155','24015','26025','18177','72021','37161','26159') AND year='2020'query — 20 rows — 2048 ms
WITH b2009 AS (
SELECT county_fips, MAX(state_abbr) AS state_abbr, COUNT(DISTINCT uninum) AS branches_2009
FROM banking.sod WHERE year = '2009' AND county_fips IS NOT NULL AND state_abbr <> 'CT'
GROUP BY county_fips
), b2024 AS (
SELECT county_fips, COUNT(DISTINCT uninum) AS branches_2024
FROM banking.sod WHERE year = '2024' AND county_fips IS NOT NULL AND state_abbr <> 'CT'
GROUP BY county_fips
), joined AS (
SELECT b2009.county_fips, state_abbr, branches_2009, COALESCE(branches_2024,0) AS branches_2024,
ROUND(100.0*(COALESCE(branches_2024,0) - branches_2009)/branches_2009, 1) AS pct_change
FROM b2009 LEFT JOIN b2024 ON b2009.county_fips = b2024.county_fips
WHERE branches_2009 >= 30
)
SELECT * FROM joined ORDER BY pct_change DESC FETCH FIRST 20 ROWS ONLYquery — 15 rows — 1166 ms
SELECT county_fips, county_name, state_fips FROM geo.counties WHERE county_fips IN ('18095','26025','18177','24017','13045','26145','26115','51710','47009','51550','37151','37001','51540','17093','13215') AND year='2020'query — 6 rows — 7326 ms
WITH top_closure(county_name, state_abbr) AS (
VALUES ('Alamance','NC'),('Carroll','GA'),('Charlottesville','VA'),('Randolph','NC'),
('Kendall','IL'),('Blount','TN'),('Muscogee','GA'),('Chesapeake','VA'),('Calhoun','MI'),
('Norfolk','VA'),('Saginaw','MI'),('Monroe','MI'),('Charles','MD'),('Wayne','IN'),('Madison','IN')
),
least_closure(county_name, state_abbr) AS (
VALUES ('Washington','VT'),('Saratoga','NY'),('Onondaga','NY'),('Rockingham','NH'),
('Kent','RI'),('Collin','TX'),('Shelby','AL'),('Kennebec','ME'),('Sarpy','NE'),
('Vermilion','IL'),('Middlesex','MA'),('Grand Forks','ND'),
('Belknap','NH'),('Denton','TX')
)
SELECT 'top_closure' AS grp,
CASE WHEN "year" BETWEEN 2009 AND 2012 THEN 'early_2009_2012'
WHEN "year" BETWEEN 2019 AND 2022 THEN 'recent_2019_2022' ELSE 'other' END AS period,
COUNT(*) AS loan_count, SUM(gross_approval) AS total_amount
FROM fiscal.sba_loan_approvals s
JOIN top_closure t ON UPPER(s.project_county) LIKE UPPER(t.county_name) || '%' AND s.project_state = t.state_abbr
WHERE "year" BETWEEN 2009 AND 2022
GROUP BY CASE WHEN "year" BETWEEN 2009 AND 2012 THEN 'early_2009_2012'
WHEN "year" BETWEEN 2019 AND 2022 THEN 'recent_2019_2022' ELSE 'other' END
UNION ALL
SELECT 'least_closure' AS grp,
CASE WHEN "year" BETWEEN 2009 AND 2012 THEN 'early_2009_2012'
WHEN "year" BETWEEN 2019 AND 2022 THEN 'recent_2019_2022' ELSE 'other' END AS period,
COUNT(*) AS loan_count, SUM(gross_approval) AS total_amount
FROM fiscal.sba_loan_approvals s
JOIN least_closure t ON UPPER(s.project_county) LIKE UPPER(t.county_name) || '%' AND s.project_state = t.state_abbr
WHERE "year" BETWEEN 2009 AND 2022
GROUP BY CASE WHEN "year" BETWEEN 2009 AND 2012 THEN 'early_2009_2012'
WHEN "year" BETWEEN 2019 AND 2022 THEN 'recent_2019_2022' ELSE 'other' END
ORDER BY grp, periodquery — 20 rows — 12074 ms
WITH top_fips(county_fips) AS (
VALUES ('37001'),('13045'),('51540'),('37151'),('17093'),('47009'),('13215'),('51550'),
('26025'),('51710'),('26145'),('26115'),('24017'),('18177'),('18095')
),
least_fips(county_fips) AS (
VALUES ('50007'),('36093'),('36085'),('33015'),('44003'),('48041'),('01089'),('23005'),
('31079'),('17199'),('25025'),('38017'),('33013'),('48209')
)
SELECT 'top_closure' AS grp, activity_year,
SUM(loans_to_small_biz_lt_1m_rev_count) AS loan_count,
SUM(loans_to_small_biz_lt_1m_rev_amount) AS loan_amount_k
FROM banking.cra_small_business_lending c
JOIN top_fips t ON c.county_fips = t.county_fips
WHERE report_level = '200'
GROUP BY activity_year
UNION ALL
SELECT 'least_closure' AS grp, activity_year,
SUM(loans_to_small_biz_lt_1m_rev_count) AS loan_count,
SUM(loans_to_small_biz_lt_1m_rev_amount) AS loan_amount_k
FROM banking.cra_small_business_lending c
JOIN least_fips t ON c.county_fips = t.county_fips
WHERE report_level = '200'
GROUP BY activity_year
ORDER BY grp, activity_yearadjust_inflation — 41033 ms
SELECT * FROM (VALUES
('top_closure', 2009, 600374000),
('top_closure', 2020, 664632000),
('least_closure', 2009, 832372000),
('least_closure', 2020, 1469787000)
) AS t(grp, yr, amt)query — 4 rows — 7072 ms
WITH top_fips(county_fips) AS (
VALUES ('37001'),('13045'),('51540'),('37151'),('17093'),('47009'),('13215'),('51550'),
('26025'),('51710'),('26145'),('26115'),('24017'),('18177'),('18095')
),
least_fips(county_fips) AS (
VALUES ('50007'),('36093'),('36085'),('33015'),('44003'),('48041'),('01089'),('23005'),
('31079'),('17199'),('25025'),('38017'),('33013'),('48209')
)
SELECT 'top_closure' AS grp, year, SUM(total_population) AS pop
FROM census.acs_population p JOIN top_fips t ON p.county_fips = t.county_fips
WHERE year IN ('2009','2020')
GROUP BY year
UNION ALL
SELECT 'least_closure' AS grp, year, SUM(total_population) AS pop
FROM census.acs_population p JOIN least_fips t ON p.county_fips = t.county_fips
WHERE year IN ('2009','2020')
GROUP BY year
ORDER BY grp, yearquery — 500 rows — 5595 ms
WITH b2009 AS (
SELECT county_fips, COUNT(DISTINCT uninum) AS br2009
FROM banking.sod WHERE year='2009' AND county_fips IS NOT NULL AND state_abbr <> 'CT'
GROUP BY county_fips
), b2020 AS (
SELECT county_fips, COUNT(DISTINCT uninum) AS br2020
FROM banking.sod WHERE year='2020' AND county_fips IS NOT NULL AND state_abbr <> 'CT'
GROUP BY county_fips
), cra09 AS (
SELECT county_fips, SUM(loans_to_small_biz_lt_1m_rev_amount) AS amt09
FROM banking.cra_small_business_lending WHERE activity_year=2009 AND report_level='200'
GROUP BY county_fips
), cra20 AS (
SELECT county_fips, SUM(loans_to_small_biz_lt_1m_rev_amount) AS amt20
FROM banking.cra_small_business_lending WHERE activity_year=2020 AND report_level='200'
GROUP BY county_fips
)
SELECT b2009.county_fips, br2009, b2020.br2020,
100.0*(b2020.br2020 - b2009.br2009)/b2009.br2009 AS branch_pct_chg,
100.0*(cra20.amt20 - cra09.amt09)/NULLIF(cra09.amt09,0) AS lending_pct_chg
FROM b2009
JOIN b2020 ON b2009.county_fips = b2020.county_fips
JOIN cra09 ON b2009.county_fips = cra09.county_fips
JOIN cra20 ON b2009.county_fips = cra20.county_fips
WHERE br2009 >= 10 AND cra09.amt09 > 0query — 1 rows — 4622 ms
WITH b2009 AS (
SELECT county_fips, COUNT(DISTINCT uninum) AS br2009
FROM banking.sod WHERE year='2009' AND county_fips IS NOT NULL AND state_abbr <> 'CT'
GROUP BY county_fips
), b2020 AS (
SELECT county_fips, COUNT(DISTINCT uninum) AS br2020
FROM banking.sod WHERE year='2020' AND county_fips IS NOT NULL AND state_abbr <> 'CT'
GROUP BY county_fips
), cra09 AS (
SELECT county_fips, SUM(loans_to_small_biz_lt_1m_rev_amount) AS amt09
FROM banking.cra_small_business_lending WHERE activity_year=2009 AND report_level='200'
GROUP BY county_fips
), cra20 AS (
SELECT county_fips, SUM(loans_to_small_biz_lt_1m_rev_amount) AS amt20
FROM banking.cra_small_business_lending WHERE activity_year=2020 AND report_level='200'
GROUP BY county_fips
), joined AS (
SELECT b2009.county_fips, br2009, b2020.br2020,
100.0*(b2020.br2020 - b2009.br2009)/b2009.br2009 AS branch_pct_chg,
100.0*(cra20.amt20 - cra09.amt09)/NULLIF(cra09.amt09,0) AS lending_pct_chg
FROM b2009
JOIN b2020 ON b2009.county_fips = b2020.county_fips
JOIN cra09 ON b2009.county_fips = cra09.county_fips
JOIN cra20 ON b2009.county_fips = cra20.county_fips
WHERE br2009 >= 10 AND cra09.amt09 > 0
)
SELECT COUNT(*) AS n, corr(branch_pct_chg, lending_pct_chg) AS r,
regr_slope(lending_pct_chg, branch_pct_chg) AS slope,
regr_intercept(lending_pct_chg, branch_pct_chg) AS intercept,
AVG(branch_pct_chg) AS avg_branch_chg, AVG(lending_pct_chg) AS avg_lending_chg
FROM joinedquantile_binning_test — 4776 ms
WITH b2009 AS (
SELECT county_fips, COUNT(DISTINCT uninum) AS br2009
FROM banking.sod WHERE year='2009' AND county_fips IS NOT NULL AND state_abbr <> 'CT'
GROUP BY county_fips
), b2020 AS (
SELECT county_fips, COUNT(DISTINCT uninum) AS br2020
FROM banking.sod WHERE year='2020' AND county_fips IS NOT NULL AND state_abbr <> 'CT'
GROUP BY county_fips
), cra09 AS (
SELECT county_fips, SUM(loans_to_small_biz_lt_1m_rev_amount) AS amt09
FROM banking.cra_small_business_lending WHERE activity_year=2009 AND report_level='200'
GROUP BY county_fips
), cra20 AS (
SELECT county_fips, SUM(loans_to_small_biz_lt_1m_rev_amount) AS amt20
FROM banking.cra_small_business_lending WHERE activity_year=2020 AND report_level='200'
GROUP BY county_fips
)
SELECT b2009.county_fips, br2009, b2020.br2020,
100.0*(b2020.br2020 - b2009.br2009)/b2009.br2009 AS branch_pct_chg,
100.0*(cra20.amt20 - cra09.amt09)/NULLIF(cra09.amt09,0) AS lending_pct_chg
FROM b2009
JOIN b2020 ON b2009.county_fips = b2020.county_fips
JOIN cra09 ON b2009.county_fips = cra09.county_fips
JOIN cra20 ON b2009.county_fips = cra20.county_fips
WHERE br2009 >= 10 AND cra09.amt09 > 0
query — 14 rows — 2394 ms
SELECT county_fips, county_name, state_fips FROM geo.counties WHERE county_fips IN ('50007','36093','36085','33015','44003','48041','01089','23005','31079','17199','25025','38017','33013','48209') AND year='2020'Sources
- Nguyen (2019), "Are Credit Markets Still Local? Evidence from Bank Branch Closings", AEJ: Applied Economics
- World Economic Forum, "How do bank branch closures affect low-income communities?"
- NCRC, Bank Branch Closures 2008-2016 Research Memo
- NCRC, Bank Branch Closure Update 2017-2020
- Fed Communities, "The financial frontier: Small business resilience in banking deserts"
- FDIC Summary of Deposits — county branch counts 2009 vs 2024
Show tool call
query(sql="branch counts by county_fips from banking.sod, year='2009' and year='2024', COUNT(DISTINCT uninum), county_fips IS NOT NULL, state_abbr <> 'CT'") - FFIEC CRA aggregate small-business lending, county totals 2009 vs 2020
Show tool call
query(sql="SUM(loans_to_small_biz_lt_1m_rev_amount) from banking.cra_small_business_lending WHERE report_level='200' AND activity_year IN (2009,2020)") - SBA 7(a)/504 loan approvals by county-group and period
Show tool call
query(sql="COUNT(*), SUM(gross_approval) from fiscal.sba_loan_approvals grouped by county group and year period") - Inflation adjustment, CPI-U, base year 2024
Show tool call
adjust_inflation(base_year=2024, index="cpi_u") - Nationwide dose-response test, branch % change vs. CRA lending % change, 1,729 counties
Show tool call
quantile_binning_test(outcome="lending_pct_chg", predictor="branch_pct_chg", bins=5)