# Peer-city comparison — sources, scope and caveats

Built Nov 2 2026. Question: is Metro Nashville's spending growth unusual among comparable consolidated (or assembled)
city-county governments? Companion files: `peer_annual.csv` (the dataset), `PEER_FINDINGS.md` (the answer),
`peer_entity_annual.csv` (one row per government per report-year before combining), `peer_fundbal_long.csv` (every
extracted table cell with page and raw token), `peer_benchmarks.csv` (population and CPI by peer and fiscal year),
`validation_report.txt`, `spot_check_report.txt`, `_extract_log.txt`. Scripts: `scripts/peers/`. Raw PDFs: `raw/peers/<city>/`
(untrusted data; every script opens them read-only and is run from the scripts folder with the PDF path as an argument).

## Peers kept and what each one is

| Peer | Governments summed | County used for population | FY ends | Years |
|---|---|---|---|---|
| **Nashville** (reference) | Metropolitan Government of Nashville & Davidson County (schools inside) | Davidson TN | Jun 30 | FY2014–FY2025 |
| **Louisville** | Louisville/Jefferson County Metro Government + Jefferson County Public Schools (JCPS) | Jefferson KY | Jun 30 | FY2015–FY2025 |
| **Jacksonville** | Consolidated City of Jacksonville + Duval County Public Schools (DCPS) | Duval FL | Sep 30 (city) / Jun 30 (DCPS) | FY2015–FY2025 |
| **Charlotte** | City of Charlotte + Mecklenburg County + Charlotte-Mecklenburg Schools (CMS) | Mecklenburg NC | Jun 30 | FY2015–FY2025 |
| **Indianapolis** | Consolidated City of Indianapolis + Marion County (separate ACFRs); **no schools** | Marion IN | Dec 31 | CY2016–CY2024 |

Two variants are carried for every city (`variant` column): `with_schools` (the like-for-like comparison with Metro
Nashville, which runs MNPS as a department) and `ex_schools` (general governments only; for Nashville the Education
current expenditures are removed). Indianapolis exists only in `ex_schools`: Marion County has eleven independent school
corporations (IPS plus township and small-city districts) and assembling them was out of reach, so it is compared
against Nashville-less-schools only.

**Dropped:** Memphis + Shelby County + MSCS (a third of Shelby County's residents live in six suburban cities with their
own police, fire and school districts, so county population is the wrong denominator for city services; the City of
Memphis FY2024/FY2025 ACFRs are also not posted anywhere a script can reach). Austin + Travis County + Austin ISD (the ISD
covers only part of the city and the county holds a dozen other districts; unlike boundaries). Both dropped rather than
compared.

## Definitions (identical to the Nashville series in `data/dashboard/annual.json`)

All figures come from the governmental-fund (modified accrual) "Changes in Fund Balances of Governmental Funds — Last
Ten Fiscal Years" table of each government's statistical section, or where noted from the audited basic statement of
the same name. Business-type activities (water, sewer, electric, airports, transit enterprises) and component units are
outside the figures everywhere.

* `total_spending` = Total expenditures of the governmental funds.
* `core_spending` = total expenditures − capital outlay = current expenditures + debt service (the Nashville "core").
* `revenues` = Total revenues of the governmental funds (blank for Nashville `ex_schools`: it cannot be split).
* `capital_outlay`, `debt_service` are carried for reference; the capital/debt lines used per government are in
  `scripts/peers/build_peer_annual.py` (`CFG`).
* Charlotte `with_schools`: Mecklenburg County's appropriation to CMS (CMS's "Mecklenburg County" revenue line, $496M in
  FY2015 → $793M in FY2025) is an expenditure of the county and again of CMS, so it is subtracted once from the combined
  spending and revenues (the `notes` column shows the amount). No other peer transfers money between its summed
  governments at that scale (JCPS and DCPS levy their own property taxes; Indianapolis and Marion County each levy
  their own).
* `population` and `cpi` are aligned to each government's own fiscal year with the Nashville rules
  (`scripts/peers/build_peer_benchmarks.py`): Census PEP July-1 county estimates (Vintage 2019 for 2010–2019 bridged
  linearly onto the Vintage 2025 base, Vintage 2025 from 2020), interpolated to the fiscal-year midpoint
  (June FY = mean of the opening and closing July-1 estimates; September FY = ¼/¾ weights; calendar year = that year's
  July-1 estimate); CPI-U all items, US city average (FRED CPIAUCSL), mean of the 12 months in the fiscal year. The
  Nashville rows reproduce `data/benchmarks_fy.csv` to four decimals. Jacksonville's combined row uses the city's
  September-year alignment; DCPS's June year sits three months earlier (caveat 2 below).

## Sources and page numbers (PDF page, 1-based)

| File (raw/peers/…) | Government, report | Table pages used | Where it came from |
|---|---|---|---|
| louisville/LouisvilleMetro_FY2025.pdf | Louisville/Jefferson County Metro Government ACFR FY2025 (Jul 2024–Jun 2025) | 175–176 (FY2016–FY2025) | louisvilleky.gov/sites/default/files/2026-01/FY25 LMG Final Audted ACFR 122225.pdf |
| louisville/LouisvilleMetro_FY2024.pdf | same, FY2024 | 172–173 (FY2015–FY2024) | louisvilleky.gov/sites/default/files/2025-01/fy24_acfr.pdf (link read in the browser pane; the HTML pages return 403 to scripts) |
| louisville/JCPS_FY2024.pdf | Board of Education of Jefferson County KY ACFR FY2024 | 130–133 (FY2015–FY2024) | education.ky.gov/districts/FinRept/Documents/FY2023-2024 FA Jefferson Co Rev.pdf |
| louisville/JCPS_FY2025.pdf (+ ocr/) | same, FY2025 — **text layer unreadable (custom font encoding)**; pages 137–140 rendered at 200 dpi and read with Apple Vision OCR (`scripts/peers/ocr_vision.swift`); labels assigned by row position from the identically laid-out FY2024 table; every year column ties to its printed totals | 137–140 (FY2016–FY2025; FY2025 used) | education.ky.gov/districts/FinRept/Documents/FY2024-2025 FA Jefferson Co.pdf |
| jacksonville/COJ_FY2025.pdf | City of Jacksonville ACFR FY2025 (Oct 2024–Sep 2025) | 329–330 (FY2016–FY2025), in thousands | jacksonville.gov archive (getContentAsset …/2025-jacksonville-ACFR-sec.pdf) |
| jacksonville/COJ_FY2024.pdf | same, FY2024 | 329–330 (FY2015–FY2024) | flauditor.gov/pages/mun_efile rpts/2024 jacksonville.pdf (Florida Auditor General e-file copy) |
| jacksonville/COJ_FY2025_single_audit.pdf | not used (single audit only) | | flauditor.gov e-file |
| jacksonville/DCPS_FY2023.pdf | Duval County Public Schools ACFR FY2023 | 182–185 (FY2014–FY2023) | flauditor.gov/pages/dsb_efile rpts/2023 duval district school board.pdf |
| jacksonville/DCPS_FY2024.pdf (+ ocr/) | DCPS FY2024 audited financial statements — **a scanned image, no text layer and no statistical section**; the governmental-funds Statement of Revenues, Expenditures and Changes in Fund Balances (p31, "Total Governmental Funds" column) was rendered at 300 dpi, OCR'd, and because the OCR dropped two cells the column was transcribed from the page image (`extract_peer_statements.py`, `DCPS24`); revenue lines sum to the printed $2,026,623,179 and expenditure lines to $2,056,783,669 | 31 (FY2024) | flauditor.gov/pages/dsb_efile rpts/2024 duval county district school board.pdf |
| jacksonville/DCPS_FY2025_AG_audit.pdf | Florida Auditor General Report 2026-135 (DCPS financial and federal single audit FY2025) — the same basic statement, "Total Governmental Funds" column; no FY2025 ACFR was posted by Nov 2 2026 | 26–27 (FY2025) | flauditor.gov/pages/pdf_files/2026-135.pdf |
| charlotte/Charlotte_FY2025_p220-221_browser_text.tsv | City of Charlotte ACFR FY2025 — **PDF not stored**: charlottenc.gov's CDN refuses scripted downloads and the bond site needs a login, so the table was read in the Claude desktop browser pane with pdf.js and saved as text (label + x-position:value per row) | 220–221 (FY2016–FY2025), in thousands | charlottenc.gov/files/sharedassets/city/v/3/…/2025/fiscal-year-2025-annual-comprehensive-financial-report.pdf |
| charlotte/Charlotte_FY2024_p212-213_browser_text.tsv | same, FY2024 | 212–213 (FY2015–FY2024) | …/2024/cacfr/fiscal-year-2024-annual-comprehensive-financial-report.pdf |
| charlotte/Charlotte_FY2021_LGC.pdf | same, FY2021 (NC Local Government Commission copy) — overlap check only | 187–188 (FY2012–FY2021) | lgreports.nctreasurer.com/Reports/2021/Municipality/Charlotte.pdf |
| charlotte/Mecklenburg_FY2025.pdf | Mecklenburg County ACFR FY2025 | 158–159 (FY2016–FY2025) | mecknc.widen.net/content/cmajmgp5fd/original/… (county portal mecknc.widencollective.com) |
| charlotte/Mecklenburg_FY2024.pdf | same, FY2024 | 157–158 (FY2015–FY2024) | mecknc.widen.net/content/gmlhsgcwio/original/… |
| charlotte/Mecklenburg_FY2021_LGC.pdf | same, FY2021 — overlap check | 153–154 (FY2012–FY2021) | lgreports.nctreasurer.com/Reports/2021/County/Mecklenburg.pdf |
| charlotte/CMS_FY2025.pdf | Charlotte-Mecklenburg Board of Education ACFR FY2025 | 92–93 (FY2016–FY2025), in thousands | cmsk12.org/fs/resource-manager/view/6bc4ebec-11de-4458-9d73-1c8650de5c20 |
| charlotte/CMS_FY2024.pdf | same, FY2024 | 102–103 (FY2015–FY2024) | cmsk12.org/fs/resource-manager/view/7334a0d0-e9d7-4ed7-b32a-e6eb351558c3 |
| indianapolis/Indianapolis_CY2024.pdf | City of Indianapolis ACFR CY2024 (State Board of Accounts filing) | 203 (CY2015–CY2024), in thousands | audit.sboa.in.gov/WebReports/14620A.pdf |
| indianapolis/Indianapolis_CY2023.pdf | same, CY2023 — overlap check | 211 (CY2014–CY2023) | in.gov/sboa/WebReports/84081A.pdf |
| indianapolis/MarionCounty_CY2024.pdf | Marion County ACFR CY2024 (the county reports separately from the city) | 204 (CY2016–CY2024; the county's table starts at 2016) | audit.sboa.in.gov/WebReports/14610A.pdf |
| indianapolis/MarionCounty_CY2023.pdf | same, CY2023 — overlap check | 201 (CY2016–CY2023) | in.gov/sboa/WebReports/84079A.pdf |

Every year is taken from the newest report that covers it. The Indianapolis and Marion County pages are stored rotated
(`/Rotate 90`); the extractor maps the word boxes into the displayed orientation before clustering rows.

## What each peer's governments do and do not include (why levels are not perfectly comparable)

* **Nashville** — one government: schools (MNPS), police, sheriff and jails, fire/EMS, General Sessions and other
  courts, public health (plus the General Hospital subsidy), social services, parks, library, public works/NDOT, codes,
  planning. Excluded as component units: WeGo transit, the Hospital Authority itself, Sports and Convention Center
  authorities, MDHA; Water Services is business-type. Six satellite cities (≈2 % of residents) keep small governments but
  receive Metro's schools, police (most) and county services.
* **Louisville** — Metro Government (2003 merger): police (LMPD), Louisville Fire for the old city only (**17 suburban fire
  protection districts are separate taxing districts and are not in the figures**), Metro Corrections (jail), EMS, public
  health, parks, the Free Public Library, public works, codes, economic development, "Related Agencies" (zoo, TARC
  support, etc.). Courts are run and paid by Kentucky's unified court system (state budget), the Jefferson County
  Sheriff is a fee-funded elected office outside Metro's governmental funds, TARC (transit), MSD (sewer) and Louisville
  Water are separate authorities/component units. About 80 small home-rule cities inside the county (≈ a fifth of
  residents) buy or run a few local services (some police). JCPS is the county-wide school district (Anchorage
  Independent, ~400 pupils, excepted).
* **Jacksonville** — the consolidated city covers all of Duval County; Atlantic Beach, Neptune Beach, Jacksonville Beach
  and Baldwin (≈4 % of residents) keep municipal governments for city-level services but receive the city's county-level
  services. Included: Sheriff's Office (police **and** jail), Fire and Rescue, libraries, parks, public works, courts
  facilities and court-related costs the county must pay (judges, prosecutors and public defenders are state-paid under
  Florida's Article V), human services. Excluded: the county health department (a Florida Department of Health unit),
  JEA (electric/water, a component unit whose "JEA contribution" is a city revenue), JTA transit, port and airport
  authorities. DCPS is the county-wide district.
* **Charlotte** — City: police (CMPD, which also serves the unincorporated county by contract), fire, solid waste,
  streets/transportation, planning and housing; water, aviation and CATS transit are enterprise funds (excluded).
  Mecklenburg County: sheriff and jail, court facilities and court-related costs (judges, DAs and clerks are state-paid
  in North Carolina), public health and social services, parks and recreation, the library system, elections, land use
  and environmental services, the register of deeds, and "Business Partners" (its appropriations to CMS, Central
  Piedmont Community College and others). CMS is the county-wide district. **The six towns (Cornelius, Davidson,
  Huntersville, Matthews, Mint Hill, Pineville; ≈16 % of county residents) run their own police, parks and some fire
  service, which are not in the figures.**
* **Indianapolis** — Consolidated City (Unigov, 1970): IMPD, Indianapolis Fire Department (several township fire
  departments, e.g. Pike, Wayne, Decatur, Perry, remain separate), public works, parks, planning, redevelopment.
  Marion County (separate ACFR since the county began reporting apart from the city): sheriff and jail/Community Justice
  Campus, the Marion Superior Court, prosecutor and public defender (county-funded; judges' salaries are state-paid),
  clerk, assessor, recorder, coroner, elections. **Not included:** the eleven school corporations, the Health and
  Hospital Corporation of Marion County (public health plus Eskenazi Health — a separate municipal corporation), the
  Indianapolis Public Library (separate), IndyGo transit, the Capital Improvement Board, township governments (poor
  relief, some fire), and the "excluded cities" (Lawrence, Speedway, Beech Grove, Southport; ≈7 % of residents). Against
  Nashville-less-schools this understates Indianapolis by its public-health and library functions (Nashville carries
  about $150M of health and $48M of library spending in FY2025).

## Validation

* `scripts/peers/build_peer_annual.py` re-adds every revenue line and every expenditure line of every government-year and
  compares them with the printed "Total revenues" and "Total expenditures": **189 government-report-years checked, 0
  failures** (tolerance $2, or 3 for tables printed in thousands) — see `validation_report.txt`.
* Overlapping reports (FY2016–FY2024 appear in two reports for most governments) agree cell-for-cell except: JCPS FY2024
  (the FY2025 report restates FY2024 total expenditures −0.4 % and revenues +4.1 %; the newer values are used),
  Jacksonville FY2024 revenues (+0.2 % in the FY2025 report), Charlotte FY2021 revenues (−0.45 % in the FY2025 report:
  FEMA accrual removed, per its footnote). Marion County CY2016–CY2023 matched once the older report's labels
  ("Capital outlays", "Interest on notes", "Lease payments") were mapped.
* Spot checks: 5 random extracted values per city (20 in all, seed 7, `scripts/peers/spot_check.py`) were printed next
  to the PDF text line (or OCR/browser text line) that carries the printed token; **all 20 were found on the recorded
  page** (`spot_check_report.txt`). The DCPS FY2024 column and the JCPS FY2025 Total Revenues / Total Expenditures
  rows were additionally eyeballed against the page images.

## Caveats that matter for the comparison

1. **Schools and the ex-schools variant.** Nashville `ex_schools` removes MNPS current expenditures only; the school
   share of Metro's debt service (roughly a quarter of the $438M debt service in FY2025) and school capital outlay stay
   in, while peers' school districts carry their own debt. Nashville-less-schools is therefore overstated by about
   $100–130M a year (3–5 %) relative to the peers' general governments. Indianapolis has no schools at all in its
   figures.
2. **Fiscal years differ.** Jacksonville's city year ends September 30 (DCPS June 30); Indianapolis and Marion County
   report calendar years. Growth multiples over ten years are barely affected; single-year levels are offset by three to
   six months against Nashville's July–June year.
3. **Who pays for courts, health, fire.** Kentucky, Florida and North Carolina fund judges, prosecutors and (in NC and KY)
   court clerks from the state budget; Tennessee's Metro Nashville pays its General Sessions judges, court clerks and
   much of the court system ($112M "Courts & justice" in FY2025). Suburban fire districts (Louisville), the state-run
   county health department (Jacksonville), the Health and Hospital Corporation and library (Indianapolis) and the six
   towns (Charlotte) sit outside the peer figures. These all push the peers' per-capita *levels* down relative to
   Nashville; they matter much less for *growth rates*.
4. **Suburban municipalities inside the county** (Louisville's small cities, Jacksonville's Beaches and Baldwin,
   Charlotte's six towns, Indianapolis's excluded cities) are counted in population but their municipal spending is
   not in the numerator. Nashville's satellite cities are the smallest such share.
5. **One-off items in the audited tables.** Louisville FY2016 carries a $110M jump in "Economic Development/APCD" (the
   Omni hotel/development commitments), which makes FY2015 an unusually low base for Louisville; the FY2016-based
   multiple is given in PEER_FINDINGS.md. Charlotte's debt-service principal includes bond-anticipation-note redemptions
   in FY2022 ($252M) and FY2024 ($329M) per its footnote (3); the "current expenditures only" lens in the findings
   removes debt service from everyone. Mecklenburg County's "Business Partners" line rises $275M in FY2023 (a
   reclassification within the county's own lines; the combined Charlotte series shows no jump).
6. **Federal pandemic money** flows through every government's revenues and spending in FY2021–FY2023 (Charlotte
   restated FY2021–FY2023 revenues for FEMA accruals; Louisville's intergovernmental revenue doubled in FY2021).
7. **Methods other than text extraction** were needed for three government-years (JCPS FY2025 by OCR, DCPS FY2024 by
   page-image transcription cross-checked with OCR, DCPS FY2025 from the Auditor General's audit rather than an ACFR) and
   Charlotte's two newest reports were read in the browser rather than stored as PDFs. Each is flagged in the `sources`
   column of `peer_annual.csv`.
8. **Marion County's table starts at 2016**, so Indianapolis runs CY2016–CY2024 (nine years); its CY2025 report was not
   yet filed with the State Board of Accounts on Nov 2 2026.
9. **CPI** is the national CPI-U for everyone (no metro CPI exists for most of these cities); regional price trends
   differed little over 2015–2025.

## Refresh

1. Drop the new ACFRs into `raw/peers/<city>/`, add them to `REPORTS` in `scripts/peers/extract_peer_tables.py` with the
   table pages (`find_pages.py <site-packages> <pdf>` locates them) and run (from the scripts folder, PDF paths as
   arguments):
   `python3 -I scripts/peers/extract_peer_tables.py "$(python3 -c 'import site;print(site.getusersitepackages())')" <project>`
2. Append the Charlotte browser-text files and the statement/OCR sources:
   `python3 -I scripts/peers/parse_charlotte_browser_text.py <tsv> <source> >> data/peers/peer_fundbal_long.csv` and
   `python3 -I scripts/peers/extract_peer_statements.py <site-packages> <project>`.
3. `python3 scripts/peers/build_peer_benchmarks.py <project>` after re-pulling `raw/benchmarks/`, then
   `python3 scripts/peers/build_peer_annual.py <project>` (check `validation_report.txt`), then
   `python3 scripts/peers/peer_findings.py <project>` for the tables in PEER_FINDINGS.md.
   (`-I` isolates the interpreter; PyMuPDF lives in the user site-packages, hence the explicit path argument.)
