Technical writing
USDA SNAP Program Data: The Federal Database Behind $100 Billion in Food Assistance
The Supplemental Nutrition Assistance Program is the largest US food assistance program — 42 million participants, $100 billion in annual benefits, and one of the largest automatic stabilizers in the federal budget. USDA FNS publishes monthly participation and benefit data, state-level administrative costs, and program integrity statistics.
From Food Stamps to SNAP: a brief history
The federal food assistance program now known as SNAP traces its origins to a Depression-era pilot and a formal program launched in 1961 under President Kennedy. For most of its existence the program operated through paper coupons redeemable at authorized grocery stores — giving rise to the colloquial name “food stamps” that persists in common usage today. The 2008 Farm Bill formally renamed the program the Supplemental Nutrition Assistance Program, a change intended to reduce stigma and reflect the shift away from paper coupons.
The paper coupon system was replaced by Electronic Benefit Transfer by 2004. Under EBT, SNAP benefits are loaded monthly onto a debit-style card that participants use at point-of-sale terminals, exactly like a standard debit transaction. The shift to EBT eliminated the secondary market for paper coupons, improved benefit delivery speed, and created a far more complete administrative data trail for program analytics. Benefits are accepted at approximately 260,000 authorized retailers across the United States, ranging from large supermarket chains to small bodegas, farmers' markets, and — since 2020 — certain online retailers.
SNAP is authorized under Title 7, Chapter 51 of the United States Code and is administered at the federal level by the Food and Nutrition Service (FNS), a USDA agency. Day-to-day program operation is delegated to state agencies, which determine eligibility, issue benefits, and manage retailer authorization within federal rules. The federal government pays 100% of benefit costs; administrative costs are split roughly 50–50 between federal and state governments, with the federal share varying by activity.
In 2023 approximately 42 million Americans received SNAP benefits in an average month. The program reached its all-time peak in December 2012, when 47.6 million participants were enrolled following the Great Recession. That peak represented approximately 15% of the US population — one in seven Americans.
Eligibility rules
SNAP eligibility is determined by a combination of income tests, an asset test, work requirements, and categorical eligibility linkages. The rules are federal minimums; states may be more generous through a mechanism called Broad-Based Categorical Eligibility (BBCE).
Gross income test. Households must have gross income at or below 130% of the federal poverty level. For a family of three in 2024, that threshold is $1,580 per month. Gross income includes wages, self-employment income, Social Security and pension income, and most other cash income before deductions.
Net income test. After deductions, net income must be at or below 100% of the federal poverty level. The deductions allowed under SNAP rules are substantive: a standard deduction available to all households; an earned income deduction of 20% on gross wages and self-employment income (rewarding work); a dependent care deduction for child care costs incurred for work or training; a medical expense deduction for elderly or disabled household members with out-of-pocket costs above $35 per month; and a shelter deduction for rent, mortgage, utilities, and homeowner's insurance exceeding 50% of net income after other deductions (capped except for households with elderly or disabled members).
Asset test. Most households must have liquid assets — bank accounts, cash, stocks and bonds, and similar resources — below $2,750. Households with at least one member who is elderly or disabled face a higher limit of $4,250. Vehicles, a home, and most retirement accounts are excluded from the asset count. However, a majority of states have eliminated the asset test entirely for most applicants through BBCE, a policy option that extends categorical eligibility to households receiving any benefit from TANF (Temporary Assistance for Needy Families), even a non-cash benefit. Because TANF categorical eligibility carries no SNAP asset test, and because states can make TANF benefits nearly universal in availability, BBCE effectively eliminates the asset test for most working families in states that adopt it.
Work requirements for ABAWDs. Able-Bodied Adults Without Dependents (ABAWDs) — adults without disabilities and without dependent children — face time-limited benefits. ABAWDs who do not work or participate in a qualifying training program for at least 20 hours per week are limited to three months of SNAP benefits within any 36-month period. This restriction was enacted in the 1996 welfare reform law as a counterpart to TANF work requirements.
A COVID-era waiver suspended ABAWD time limits nationally from March 2020 through April 2023, when the COVID public health emergency ended. The Fiscal Responsibility Act of 2023 — the debt ceiling compromise enacted in June 2023 — tightened ABAWD rules by raising the age ceiling from 49 to 52 (effective October 2023) and narrowing some work-requirement exemptions, while simultaneously expanding rural area exemptions that allow states to waive work requirements in counties with elevated unemployment. The net effect on enrollment of those competing changes became a subject of ongoing administrative monitoring by USDA FNS.
Categorical eligibility. Certain populations are automatically eligible for SNAP without passing the income and asset tests individually. SSI (Supplemental Security Income) recipients are categorically eligible in most states, as are most TANF cash recipients. Categorical eligibility greatly simplifies the application and renewal process for these populations and is one reason SNAP participation rates among SSI recipients are very high.
Benefit amounts and the Thrifty Food Plan
SNAP maximum benefit allotments are set by the Thrifty Food Plan (TFP), a USDA model of the least expensive dietary pattern that nonetheless meets federal nutritional standards. The TFP specifies a market basket of foods and quantities for reference households of various sizes; USDA prices that basket using national retail food prices and adjusts it annually for food price inflation using USDA cost-of-food data.
From the program's founding in 1964 through 2021, the TFP had never been substantively redesigned — only price-indexed. A 2021 comprehensive review of the TFP methodology, required by the 2018 Farm Bill, resulted in a redesigned market basket that reflected current nutritional science, contemporary American food purchasing patterns, and realistic preparation time constraints. The new TFP raised the maximum SNAP allotment by approximately 25% — the largest real increase in the program's history and the first meaningful benefit increase since 1975 in inflation-adjusted terms.
Maximum monthly allotments for fiscal year 2024 are: $291 for a one-person household; $535 for a two-person household; $766 for a three-person household; $975 for a four-person household; $1,158 for a five-person household; $1,390 for a six-person household; and $1,573 for a seven-person household. Households of eight members receive up to $1,756; each additional person adds $219 per month. A household's actual benefit equals the maximum for its size minus 30% of its net income (the 30% rate reflecting the expected household contribution toward food).
Average monthly benefits per person in 2023 were approximately $185, substantially below the maximum because most participants have some net income. This figure represents a sharp drop from the emergency allotment (EA) period during COVID. Emergency allotments — authorized under the Families First Coronavirus Response Act — guaranteed every SNAP household at least the maximum benefit for its size, regardless of net income. For households already receiving maximum benefits, this had no effect; for the majority receiving partial benefits, EA added a minimum of $95 per month. Emergency allotments ended in February 2023 across all states, causing approximately 14 million households to lose an average of $82 per month in SNAP benefits in a single month — one of the sharpest sudden reductions in food assistance purchasing power in program history.
SNAP as an automatic stabilizer
SNAP is designed to expand automatically in economic downturns without requiring a specific congressional appropriation vote. As unemployment rises and household incomes fall, more families cross below the income eligibility thresholds and begin receiving benefits; as the economy recovers, incomes rise, households become ineligible, and caseloads shrink. This automatic counter-cyclicality is the defining feature of a fiscal automatic stabilizer.
Moody's Analytics has estimated SNAP's fiscal multiplier at approximately 1.54 — meaning each dollar of SNAP benefits generates $1.54 in economic activity. This is among the highest fiscal multipliers of any federal program, reflecting the high marginal propensity to consume of SNAP recipients (who spend benefits almost immediately on food) and the localized spending pattern that cycles through grocery retail into local supply chains. By comparison, the multiplier estimates for tax cuts directed at higher-income households are typically well below 1.0.
The Great Recession episode illustrates the stabilizer function clearly. National SNAP participation stood at approximately 26 million in 2007, before the recession began. By December 2012, participation had reached 47.6 million — an increase of roughly 83% in five years, tracking the surge in unemployment and the slow recovery of household incomes. The program did not require new legislation to expand; the eligibility rules simply captured the population falling below the income thresholds. The Congressional Budget Office and the Federal Reserve have both cited SNAP as a key automatic stabilizer in post-recession fiscal analyses.
The COVID expansion followed a similar but compressed arc. Participation stood at approximately 36 million in February 2020 before the pandemic hit. By April 2021, the count had risen to approximately 43 million — a 19% increase in 14 months, driven by job losses, business closures, and the eligibility relaxations in some states. The COVID expansion was smaller in percentage terms than the Great Recession surge because the 2020 recession was shorter, the recovery more rapid, and the income-based eligibility test selected less severely than the prolonged unemployment of 2009–2013.
Program integrity: error rates and retailer trafficking
USDA FNS tracks two primary program integrity metrics: the payment error rate and the retailer trafficking rate. These are distinct phenomena requiring different detection and remediation approaches.
Payment error rate (PER). The PER measures overpayments and underpayments as a percentage of total benefits issued. A payment error can be caused by state agency mistakes in calculating eligibility or benefit amounts, by applicant-provided incorrect information, or by failures to update cases promptly when circumstances change. The PER does not measure fraud; it measures the accuracy of benefit determination, including both agency and client errors.
USDA uses the PER to assess state agency performance and impose fiscal sanctions. States whose PER exceeds 105% of the national average rate for two consecutive years face fiscal sanctions requiring the state to reimburse the federal government for a portion of excess error costs. This creates a financial incentive for states to invest in eligibility determination accuracy. The national FY2022 payment error rate was approximately 6.5%, a figure that includes both overpayments (the larger component) and underpayments.
Fraud — where a recipient or an applicant intentionally provides false information to obtain or retain benefits — is a subset of errors and is tracked separately. SNAP disqualifies individuals found to have committed intentional program violations (IPV) for periods ranging from one year for a first offense to permanent disqualification for a third offense or for trading benefits for firearms, drugs, or explosives.
Retailer trafficking. Trafficking refers to the illegal exchange of SNAP benefits for cash — a retailer or individual accepts SNAP EBT as payment and gives the participant cash at a discount, typically around 50 cents on the dollar. The retailer then submits the full face value for USDA reimbursement, effectively laundering the discount as profit. USDA estimates the SNAP trafficking rate at approximately 1.0–1.5% of total benefits, based on periodic national trafficking studies using statistical analysis of EBT transaction patterns to identify transactions inconsistent with legitimate retail food purchases.
USDA's Retailer Integrity Branch monitors authorized retailers using transaction-pattern analysis, undercover investigations, and retailer disqualification proceedings. Retailers found to have trafficked benefits are permanently disqualified from SNAP participation and may face civil monetary penalties. The shift to EBT was instrumental in enabling this detection: the electronic transaction record allows statistical identification of stores with unusual transaction patterns (excessive large transactions, high frequencies of even-dollar amounts, abnormally high benefit redemption relative to stock), which was impossible with paper coupons.
SNAP online purchasing. Since 2019, USDA has expanded a pilot allowing SNAP participants to use EBT benefits for online grocery orders. Amazon and Walmart were the first authorized online retailers; by 2024 the program had expanded to include Kroger, Aldi, and several regional chains across 49 states. Online purchasing extends SNAP's reach to participants with mobility limitations, those without nearby authorized retailers, and those in food deserts where physical stores stock limited healthy options.
Data available from USDA FNS
USDA FNS publishes an extensive set of SNAP administrative data, though most of it arrives as Excel or PDF files rather than through a machine-readable API.
Monthly participation and benefit tables. The primary SNAP data publication at fns.usda.gov/pd/supplemental-nutrition-assistance-program-snap contains national and state-level monthly participation counts and total benefit amounts going back to the program's early history. The tables are published as Excel files, typically with a one-to-two-month lag. These are the foundational data series for any SNAP trend analysis.
SNAP Retailer Locator data. USDA publishes a nationwide database of authorized SNAP retailers, downloadable as a data file, with store name, address, ZIP code, county, store type, and authorization status. This dataset is used to analyze retailer geographic coverage, identify food desert overlap, and track the expansion of online retailer authorization. The data is updated frequently as retailers are authorized and disqualified.
State administrative data. FNS publishes state-level payment error rates, administrative costs per case, and other operational metrics annually. These data allow comparison of state administrative efficiency and are used to compute the sanctions threshold for states with elevated error rates.
Characteristics of SNAP Households. USDA FNS publishes an annual report based on a detailed survey of SNAP participants, covering household composition (single adults, families with children, elderly households, households with disabled members), income sources (wages, Social Security, TANF, no income), benefit amounts, and the share of income devoted to food. This report is the primary source for understanding who receives SNAP benefits rather than just how many. In FY2022, approximately 38% of SNAP households contained a child; 21% had an elderly or disabled member; and approximately 32% of households had earned income from wages, reflecting that a substantial fraction of SNAP recipients are working but earning too little to meet food needs without assistance.
Data.gov and FRED mirrors. USDA FNS participates in the federal data.gov initiative and posts some SNAP datasets there. The Federal Reserve Bank of St. Louis's FRED database mirrors key SNAP aggregate series — including monthly national participation counts and total benefit redemptions — and exposes them through a freely accessible CSV API, making FRED the most convenient programmatic access point for SNAP time-series data.
There is no dedicated USDA FNS SNAP public API. Researchers working with SNAP data at scale typically download the Excel files published at fns.usda.gov and parse them programmatically, or use the FRED API for the aggregate time series. State-level claims data and individual-level participant data are not publicly released; access requires a data use agreement with the relevant state agency or USDA.
Python: analyzing SNAP participation trends (2005–2023)
The following script retrieves SNAP participation and benefit data from the FRED API, computes annual participation averages and total benefits from 2005 through 2023, annotates each year by economic era, tracks the benefit-per-person trend across the 2021 Thrifty Food Plan redesign, and compares state participation rates per capita using representative USDA FNS administrative data. Install dependencies with pip install requests pandas.
import requests
import pandas as pd
from io import StringIO
# -----------------------------------------------------------------------
# SNAP Participation & Benefit Trend Analyzer (2005-2023)
#
# Data source: FRED (Federal Reserve Bank of St. Louis), which mirrors
# USDA FNS SNAP monthly participation and benefit data.
# SNAPCILM = SNAP participants (thousands, monthly, not seasonally adj.)
# SNAPABMT = Total SNAP benefit redemptions (millions of dollars, monthly)
#
# Both series are derived from USDA FNS administrative records.
# FRED API requires no key for basic CSV retrieval.
# -----------------------------------------------------------------------
FRED_BASE = "https://fred.stlouisfed.org/graph/fredgraph.csv"
def fetch_fred(series_id: str, start: str = "2005-01-01") -> pd.Series:
url = f"{FRED_BASE}?id={series_id}&observation_start={start}"
resp = requests.get(url, timeout=30)
resp.raise_for_status()
df = pd.read_csv(StringIO(resp.text), parse_dates=["DATE"])
df = df[df[series_id] != "."]
df[series_id] = df[series_id].astype(float)
return df.set_index("DATE")[series_id]
print("Downloading SNAP participation data from FRED ...")
participants_k = fetch_fred("SNAPCILM") # thousands of participants
benefits_m = fetch_fred("SNAPABMT") # millions of dollars in benefits
# Convert to natural units
participants = participants_k * 1_000 # actual persons
benefits_b = benefits_m / 1_000 # billions of dollars
# -----------------------------------------------------------------------
# Step 1: Annual averages (calendar year)
# -----------------------------------------------------------------------
annual_part = participants.resample("YE").mean().rename("avg_participants")
annual_ben = benefits_b.resample("YE").sum().rename("total_benefits_b")
annual = pd.concat([annual_part, annual_ben], axis=1).dropna()
annual.index = annual.index.year
# Average monthly benefit per person (annualized total / 12 / avg participants)
annual["benefit_per_person_mo"] = (
annual["total_benefits_b"] * 1e9 / 12 / annual["avg_participants"]
).round(2)
print("\n=== Annual SNAP Participation and Benefits (2005-2023) ===")
col_year = "Year"
col_part = "Avg Participants"
col_ben = "Total Benefits ($B)"
col_bpp = "$/Person/Month"
header = f"{col_year:<6} {col_part:>18} {col_ben:>20} {col_bpp:>16}"
print(header)
for yr, row in annual.iterrows():
line = (
f"{yr:<6} {row['avg_participants']:>18,.0f} "
+ f"{row['total_benefits_b']:>20.1f} "
+ " $" + f"{row['benefit_per_person_mo']:.2f}"
)
print(line)
# -----------------------------------------------------------------------
# Step 2: Recession vs. recovery annotation
# -----------------------------------------------------------------------
recession_years = set(range(2008, 2014)) # Great Recession surge
pandemic_years = set(range(2020, 2022)) # COVID surge
def era(yr):
if yr in recession_years:
return "Great Recession / aftermath"
if yr in pandemic_years:
return "COVID pandemic"
if yr < 2008:
return "Pre-recession"
return "Recovery / baseline"
print("\n=== Participation by Era ===")
for yr, row in annual.iterrows():
print(f" {yr}: {row['avg_participants']:>12,.0f} participants ({era(yr)})")
# Key milestones
peak_yr = annual["avg_participants"].idxmax()
trough_yr = annual.loc[annual.index >= 2013, "avg_participants"].idxmin()
print(f"\nPeak participation: {annual.loc[peak_yr, 'avg_participants']:,.0f} "
f"(annual avg {peak_yr}; USDA reports December 2012 monthly peak of 47.6M)")
print(f"Post-recession trough: {annual.loc[trough_yr, 'avg_participants']:,.0f} "
f"({trough_yr})")
# -----------------------------------------------------------------------
# Step 3: Benefits per person trend
# -----------------------------------------------------------------------
ben_2005 = annual.loc[2005, "benefit_per_person_mo"]
ben_2021 = annual.loc[2021, "benefit_per_person_mo"] # Thrifty Food Plan update year
ben_2023 = annual.loc[2023, "benefit_per_person_mo"]
print(f"\n=== Benefit per Person per Month Trend ===")
print(" 2005 : $" + f"{ben_2005:.2f}")
print(" 2021 : $" + f"{ben_2021:.2f}" + " (TFP update, ~25% real increase)")
print(" 2023 : $" + f"{ben_2023:.2f}" + " (post-emergency-allotment end Feb 2023)")
print(f" Change 2005-2023: +{((ben_2023/ben_2005)-1)*100:.1f}%")
# -----------------------------------------------------------------------
# Step 4: State-level participation rates per capita (2022 ACS population)
# -----------------------------------------------------------------------
# USDA FNS publishes state-level SNAP participation data in Excel files at
# fns.usda.gov/pd/supplemental-nutrition-assistance-program-snap
# The data below is representative FY2022 state-level enrollment from
# USDA FNS tables (State Program Activity Reports), paired with
# 2022 Census population estimates.
state_data = {
"Alabama": {"participants": 797_000, "population": 5_074_296},
"Alaska": {"participants": 99_000, "population": 733_583},
"Arizona": {"participants": 919_000, "population": 7_359_197},
"Arkansas": {"participants": 373_000, "population": 3_045_637},
"California": {"participants": 4_282_000,"population": 39_029_342},
"Colorado": {"participants": 448_000, "population": 5_839_926},
"Connecticut": {"participants": 335_000, "population": 3_626_205},
"Delaware": {"participants": 132_000, "population": 1_018_396},
"Florida": {"participants": 3_070_000,"population": 22_244_823},
"Georgia": {"participants": 1_360_000,"population": 10_912_876},
"Hawaii": {"participants": 168_000, "population": 1_440_196},
"Idaho": {"participants": 175_000, "population": 1_939_033},
"Illinois": {"participants": 1_750_000,"population": 12_582_032},
"Indiana": {"participants": 608_000, "population": 6_833_037},
"Iowa": {"participants": 290_000, "population": 3_200_517},
"Kansas": {"participants": 202_000, "population": 2_937_880},
"Kentucky": {"participants": 578_000, "population": 4_512_310},
"Louisiana": {"participants": 762_000, "population": 4_590_241},
"Maine": {"participants": 184_000, "population": 1_385_340},
"Maryland": {"participants": 696_000, "population": 6_164_660},
"Massachusetts": {"participants": 862_000, "population": 6_981_974},
"Michigan": {"participants": 1_245_000,"population": 10_034_113},
"Minnesota": {"participants": 470_000, "population": 5_717_184},
"Mississippi": {"participants": 457_000, "population": 2_940_057},
"Missouri": {"participants": 627_000, "population": 6_177_957},
"Montana": {"participants": 103_000, "population": 1_122_867},
"Nebraska": {"participants": 147_000, "population": 1_967_923},
"Nevada": {"participants": 365_000, "population": 3_177_772},
"New Hampshire": {"participants": 87_000, "population": 1_395_231},
"New Jersey": {"participants": 784_000, "population": 9_261_699},
"New Mexico": {"participants": 406_000, "population": 2_113_344},
"New York": {"participants": 2_987_000,"population": 19_677_151},
"North Carolina": {"participants": 1_279_000,"population": 10_698_973},
"North Dakota": {"participants": 53_000, "population": 779_261},
"Ohio": {"participants": 1_437_000,"population": 11_756_058},
"Oklahoma": {"participants": 549_000, "population": 4_019_800},
"Oregon": {"participants": 698_000, "population": 4_240_137},
"Pennsylvania": {"participants": 1_661_000,"population": 12_972_008},
"Rhode Island": {"participants": 146_000, "population": 1_093_734},
"South Carolina": {"participants": 621_000, "population": 5_282_634},
"South Dakota": {"participants": 101_000, "population": 909_824},
"Tennessee": {"participants": 912_000, "population": 7_051_339},
"Texas": {"participants": 3_540_000,"population": 30_029_572},
"Utah": {"participants": 196_000, "population": 3_380_800},
"Vermont": {"participants": 88_000, "population": 647_064},
"Virginia": {"participants": 793_000, "population": 8_683_619},
"Washington": {"participants": 948_000, "population": 7_785_786},
"West Virginia": {"participants": 285_000, "population": 1_775_156},
"Wisconsin": {"participants": 533_000, "population": 5_892_539},
"Wyoming": {"participants": 37_000, "population": 581_381},
}
df_states = pd.DataFrame.from_dict(state_data, orient="index")
df_states["participation_rate"] = (
df_states["participants"] / df_states["population"] * 100
).round(1)
df_states = df_states.sort_values("participation_rate", ascending=False)
print("\n=== Top 10 States by SNAP Participation Rate (FY2022) ===")
top10 = df_states.head(10)
for state, row in top10.iterrows():
print(f" {state:<20} {row['participation_rate']:>5.1f}% "
f"({row['participants']:>10,.0f} participants)")
print("\n=== Bottom 10 States by SNAP Participation Rate (FY2022) ===")
bot10 = df_states.tail(10).sort_values("participation_rate")
for state, row in bot10.iterrows():
print(f" {state:<20} {row['participation_rate']:>5.1f}% "
f"({row['participants']:>10,.0f} participants)")
national_rate = (
df_states["participants"].sum() / df_states["population"].sum() * 100
)
print(f"\nNational average participation rate: {national_rate:.1f}%")
Several notes for production use. The FRED series SNAPCILM reports participants in thousands and is not seasonally adjusted; annual averages calculated from monthly data will match published USDA annual averages closely but may differ by rounding. The series SNAPABMT reports total benefit redemptions in millions of dollars. FRED typically carries these series with a one-to-two-month lag relative to the USDA FNS publication; check the series vintage date if you need the most recent month.
The state-level participation figures in the script are representative FY2022 administrative totals from USDA FNS State Program Activity Reports, paired with 2022 Census population estimates. For updated state-level data, download the current Excel tables from fns.usda.gov/pd/supplemental-nutrition-assistance-program-snap and parse the state-level tabs. State participation rates vary substantially based on demographics, state policy choices (BBCE adoption, outreach funding, benefit access infrastructure), and underlying poverty rates. Mississippi, Louisiana, and West Virginia consistently show among the highest participation rates; Wyoming, North Dakota, and New Hampshire among the lowest — a pattern that tracks closely with poverty rates, rural food access conditions, and state BBCE policy.
The benefit-per-person calculation divides total annual redemptions by 12 and by average monthly participation. This approximates the average monthly benefit per recipient but will differ from the average benefit per household (since household sizes vary) reported in the Characteristics of SNAP Households report. Analysts distinguishing between individual-level and household-level benefit amounts should use the Characteristics report for household averages and the FRED series for aggregate totals.
Related: Census CPS poverty statistics · HHS Medicaid enrollment data
Part of the Federal Regulatory Data Hub.