Fastest-growing Texas county
Kaufman County
+39.4% from 2019 to 2024
Working example · Census population change API
Use PrairieCloud to pull ACS population data for every Texas county, compare 2019 vs. 2024, and drill into Denton County census tracts without decoding Census table IDs or maintaining FIPS lookup tables.
Result preview
Fastest-growing Texas county
Kaufman County
+39.4% from 2019 to 2024
Largest decline
Kenedy County
-74.5% from 2019 to 2024
Denton County
833,822 → 979,561
+17.5% population change
Denton tract detail
54 grew · 41 shrank
98 lacked a 2019 baseline in the matched response
Outcome snapshot
This example uses the same API surface your application would use: REST requests, JSON responses, and stable geography keys. No one-off spreadsheet export. No Census codebook archaeology.
Where did Texas grow from ACS 2019 to ACS 2024, and what happened inside one fast-growing county?
Step 1
Start with the latest ACS 5-Year population estimate for every Texas county. The variable is readable: pop_total. The geography is readable too: county:Texas.
curl -H "X-API-Key: $PRAIRIECLOUD_API_KEY" \
"https://api.prairiecloud.io/v1/data?variables=pop_total&geo=county:Texas&vintage=2024&dataset=acs5"{
"data": {
"county:48001": {
"geo_key": "county:48001",
"name": "Anderson County, Texas",
"geo_type": "county",
"variables": {
"pop_total": {
"api_name": "pop_total",
"label": "Total population",
"estimate": 58439,
"margin_of_error": null
}
}
},
"county:48121": {
"geo_key": "county:48121",
"name": "Denton County, Texas",
"geo_type": "county",
"variables": {
"pop_total": {
"api_name": "pop_total",
"label": "Total population",
"estimate": 979561,
"margin_of_error": null
}
}
}
},
"meta": {
"source": {
"dataset": "acs5",
"vintage_year": 2024,
"reference_period": "2020-2024"
},
"variable_count": 1,
"geography_count": 254
}
}Step 2
Request the same geography and variable for two ACS vintages, join by geo_key, and calculate change. The response shape does not change between years.
import os
import requests
API_KEY = os.environ["PRAIRIECLOUD_API_KEY"]
BASE_URL = "https://api.prairiecloud.io/v1/data"
HEADERS = {"X-API-Key": API_KEY}
def fetch_texas_county_population(vintage: int):
response = requests.get(
BASE_URL,
headers=HEADERS,
params={
"variables": "pop_total",
"geo": "county:Texas",
"vintage": vintage,
"dataset": "acs5",
},
timeout=30,
)
response.raise_for_status()
return response.json()["data"]
pop_2019 = fetch_texas_county_population(2019)
pop_2024 = fetch_texas_county_population(2024)
rows = []
for geo_key, current in pop_2024.items():
previous = pop_2019[geo_key]
current_pop = current["variables"]["pop_total"]["estimate"]
previous_pop = previous["variables"]["pop_total"]["estimate"]
if previous_pop and current_pop is not None:
pct_change = (current_pop - previous_pop) / previous_pop * 100
rows.append({
"county": current["name"],
"pop_2019": int(previous_pop),
"pop_2024": int(current_pop),
"pct_change": pct_change,
})
rows.sort(key=lambda row: row["pct_change"], reverse=True)
for row in rows[:10]:
print(
f"{row['county']}: "
f"{row['pop_2019']:,} → {row['pop_2024']:,} "
f"({row['pct_change']:+.1f}%)"
)Kaufman County, Texas: 123,804 → 172,604 (+39.4%)
Comal County, Texas: 141,642 → 183,826 (+29.8%)
Rockwall County, Texas: 97,175 → 123,617 (+27.2%)
Bastrop County, Texas: 84,522 → 106,582 (+26.1%)
Hays County, Texas: 213,366 → 268,638 (+25.9%)
Chambers County, Texas: 41,305 → 51,498 (+24.7%)
Liberty County, Texas: 83,702 → 103,380 (+23.5%)
Parker County, Texas: 133,811 → 165,168 (+23.4%)
Williamson County, Texas: 547,604 → 672,688 (+22.8%)
Ellis County, Texas: 173,772 → 213,160 (+22.7%)Step 3
County-level growth is useful, but most real decisions happen below the county line. Move from county to tract detail using the same variable and the same response shape.
curl -H "X-API-Key: $PRAIRIECLOUD_API_KEY" \
"https://api.prairiecloud.io/v1/data?variables=pop_total&geo=tract:Denton%20County,%20Texas&vintage=2024&dataset=acs5"def fetch_denton_tract_population(vintage: int):
response = requests.get(
BASE_URL,
headers=HEADERS,
params={
"variables": "pop_total",
"geo": "tract:Denton County, Texas",
"vintage": vintage,
"dataset": "acs5",
},
timeout=30,
)
response.raise_for_status()
return response.json()["data"]
tracts_2019 = fetch_denton_tract_population(2019)
tracts_2024 = fetch_denton_tract_population(2024)
grew = shrank = no_2019_baseline = 0
changes = []
for geo_key, current in tracts_2024.items():
current_pop = current["variables"]["pop_total"]["estimate"]
previous_pop = tracts_2019[geo_key]["variables"]["pop_total"]["estimate"]
if not previous_pop:
no_2019_baseline += 1
continue
pct_change = (current_pop - previous_pop) / previous_pop * 100
changes.append((pct_change, current["name"], previous_pop, current_pop))
if pct_change > 0:
grew += 1
elif pct_change < 0:
shrank += 1
print(f"Existing tracts that grew: {grew}")
print(f"Existing tracts that shrank: {shrank}")
print(f"Tracts without a 2019 population baseline: {no_2019_baseline}")
for pct_change, name, previous_pop, current_pop in sorted(changes, reverse=True)[:5]:
print(f"{name}: {previous_pop:,.0f} → {current_pop:,.0f} ({pct_change:+.1f}%)")Existing tracts that grew: 54
Existing tracts that shrank: 41
Tracts without a 2019 population baseline: 98
Census Tract 201.09; Denton County; Texas: 7,033 → 12,093 (+71.9%)
Census Tract 204.02; Denton County; Texas: 5,495 → 8,868 (+61.4%)
Census Tract 205.04; Denton County; Texas: 3,506 → 5,365 (+53.0%)
Census Tract 202.04; Denton County; Texas: 4,403 → 6,706 (+52.3%)
Census Tract 218; Denton County; Texas: 3,611 → 5,163 (+43.0%)Why it matters
You could build this directly on the Census Bureau API. PrairieCloud is for teams that would rather spend their time on the product layer.
Build your own
Swap county:Texas for another state or tract:Denton County, Texas for another county. The API returns the same structure, so your code does not need to change just because the geography changes.
Free tier. No credit card. 1,000 requests/month.
Learn variables, vintages, geography syntax, and response structure.
Find readable API names for income, housing, education, and more.
Use GeoJSON boundaries when your workflow needs a map, not just a table.
No credit card. 1,000 requests/month on the free tier.