Research / 2026-09-10

Which hospital operator has the most Medicaid exposure? A facility-level answer

Summed across FY2024 cost reports, Acadia, Ardent and Tenet carry the highest Medicaid share of inpatient days among listed operators, HCA carries the highest uncompensated care share, and all of them sit below the sector aggregate on Medicaid days.

Why this matters

When a Medicaid headline lands, the first question is which listed names carry the exposure. The companies answer in their own terms, not comparably. Every hospital files the same cost report, with Medicaid inpatient days, uncompensated care and bad debt on fixed lines. Summing those lines by owner gives a like-for-like answer, and the same table gives the sector figure to size it against. This note does that for FY2024.

Method

Source rows. hcris_hospital_reports. FY2024 is the latest fiscal year with full coverage: 6,045 CCNs have an FY2024 report against 6,040 for FY2023 and 3,475 for FY2025 (query A). One report per CCN is kept, latest fiscal year end first.

Operator. provider_operator_crosswalk, one row per CCN using the export rule (ticker-bearing row first, then largest ownership share). REIT landlords carry a ticker too, so Medical Properties Trust appears for the 24 hospitals where it is the only ticker on the CCN.

Measures. Medicaid inpatient days over total inpatient days. Uncompensated care (Worksheet S-10) over total revenues. Bad debt over total revenues. All three are sums across the operator's hospitals. The sector row is the same sum across all 6,045 filers; a second sector row is the median of per-hospital shares.

Dropped measure. Medicaid charges over total charges is not reported. medicaid_charges is populated on 539 of 6,107 FY2023 rows and none of 6,134 FY2024 rows; medicaid_costs on none (query C).

Missing lines. A hospital without a line adds nothing to that numerator but stays in the denominator. The download counts hospitals missing each line per operator. Nationally 5,057 of 6,134 FY2024 rows carry Medicaid days and 4,564 carry uncompensated care (query C).

The table by ticker, FY2024

Ticker Operator Hospitals Total revenues ($bn) Medicaid share of inpatient days Uncompensated care / revenues Bad debt / revenues
ACHC Acadia Healthcare 49 1.71 8.7% 0.4% 0.6%
ARDT Ardent Health 28 5.01 8.5% 3.9% 0.6%
THC Tenet Healthcare 56 13.32 8.2% 3.7% 0.2%
CYH Community Health Systems 47 7.43 7.7% 4.4% 0.6%
UHS Universal Health Services 147 12.81 7.0% 3.9% 0.6%
MPW Medical Properties Trust (landlord) 24 0.96 5.9% 5.3% 13.1%
HCA HCA Healthcare 157 57.45 5.3% 6.7% 0.6%
SEM Select Medical 107 3.90 3.3% 0.0% 1.2%
SGRY Surgery Partners 16 1.42 2.3% 1.9% 0.3%
EHC Encompass Health 160 5.11 1.8% n/a 2.3%
Sector All 6,045 filers, sums 6,045 1,450.64 8.7% 5.5% 3.4%
Sector All filers, median hospital 6,045 4.7% 5.2% 0.9%

Operators with five or fewer cost reports (UNH, NHC, ENSG, ADUS) are in the download, not the table.

Three readings. No listed acute-care operator reaches the sector aggregate of 8.7% Medicaid days; the aggregate is pulled up by public and safety-net hospitals, and the median hospital sits at 4.7%. HCA has the highest uncompensated care share among acute operators at 6.7%, above the sector aggregate of 5.5%, on the largest revenue base. Encompass and Select are rehabilitation and long-term acute care operators; the uncompensated care line is blank on 160 of 160 and 106 of 107 of their reports, so the column says nothing about their exposure.

The MPW row is a landlord. Its 13.1% bad debt share sums 24 tenant hospitals whose operator has no ticker in the crosswalk.

The spread within an operator

For HCA, 151 of 157 FY2024 reports carry usable day counts (query D). The five highest Medicaid day shares:

CCN Hospital State Medicaid share of days Uncompensated care / revenues Revenues ($m)
060065 North Suburban Medical Center CO 31.2% 23.2% 222.6
130014 West Valley Medical Center ID 27.3% 4.6% 119.5
020017 Alaska Regional Hospital AK 23.3% 2.9% 362.2
130018 Eastern Idaho Regional Medical Center ID 22.6% 3.2% 425.5
060034 Swedish Medical Center CO 20.6% 8.1% 683.5

The five lowest:

CCN Hospital State Medicaid share of days Uncompensated care / revenues Revenues ($m)
444029 Pinewood Springs TN 0.15% blank 16.4
341316 Highlands Cashiers Hospital NC 0.12% 7.1% 24.8
450804 Texas Orthopedic Hospital TX 0.10% 0.2% 284.1
454094 Medical City Green Oaks Hospital TX 0.09% blank 40.3
450713 South Austin Medical Center TX 0.07% 8.4% 578.9

The bottom is not all small specialty facilities. South Austin Medical Center reports $579m of revenue and 106,580 inpatient days with 79 attributed to Medicaid, alongside an 8.4% uncompensated care share. Whether that is payer coding on Worksheet S-3 or the Texas coverage environment cannot be settled from the cost report. Read the two shares together before quoting the operator figure.

Limits

Lag. FY2024 reports, loaded 2026-05-23 (query A). Fiscal years end in different months, so FY2024 spans windows ending anywhere in calendar 2024. Nothing from 2025 is in this data.

Amendments. Each hospital fiscal year appears once, with the latest filed figures; no filing history is kept (docs/data-dictionaries/hcris_hospital_financials.md).

Medicaid days as filed. The line is what the hospital entered on Worksheet S-3. Treatment of Medicaid managed care days is not uniform; South Austin shows how far it can sit from the uncompensated care line.

Control type coding. control_type holds the raw CMS numeric code on 5,859 of 6,134 FY2024 rows (query C). This note groups by ticker, so it does not affect the table, but a for-profit versus non-profit denominator needs the codes mapped first.

Crosswalk provenance. The CCN to owner link is CMS's; the owner to ticker link is ours. match_method isolates the CMS-evidenced subset (docs/data-dictionaries/operator_crosswalk.md).

CSV download

data/hospital-operator-medicaid-exposure.csv: one row per ticker for FY2024 with hospital count, revenues, the three shares and missing-line counts, then the two sector rows.

Appendix: queries

Read-only against production Postgres, 2026-09-10, statement_timeout = '60s'. All queries filter on fy_end_year, ccn or ticker, which are indexed. Every query in this note ran.

Query A. Coverage by fiscal year.

SELECT fy_end_year, count(DISTINCT ccn) AS ccns, max(ingested_at)::date AS last_ingested
FROM hcris_hospital_reports WHERE fy_end_year BETWEEN 2021 AND 2025 GROUP BY 1 ORDER BY 1;

Result: 2021 5,996; 2022 6,008; 2023 6,040; 2024 6,045; 2025 3,475. All last ingested 2026-05-23.

Query B. Exposure by ticker plus sector rows (the download).

WITH x AS (
  SELECT ccn, ticker, entity_class, operator_legal_name FROM (
    SELECT ccn, ticker, entity_class, operator_legal_name, row_number() OVER (PARTITION BY ccn ORDER BY (ticker IS NOT NULL) DESC, ownership_pct DESC NULLS LAST, operator_key) AS rn
    FROM provider_operator_crosswalk) t WHERE rn = 1 AND ticker IS NOT NULL),
hr AS (
  SELECT * FROM (
    SELECT h.*, row_number() OVER (PARTITION BY ccn ORDER BY fy_end DESC, ingested_at DESC) AS rn
    FROM hcris_hospital_reports h WHERE fy_end_year = 2024) s WHERE rn = 1),
t AS (
  SELECT x.ticker, x.entity_class, min(x.operator_legal_name) AS operator, count(*) AS hospitals,
    round(sum(hr.total_revenues)/1e9, 2) AS total_revenues_busd,
    round(sum(hr.medicaid_inpatient_days)::numeric / nullif(sum(hr.total_inpatient_days),0), 4) AS medicaid_days_share,
    round(sum(hr.uncompensated_care)::numeric / nullif(sum(hr.total_revenues),0), 4) AS uncompensated_care_share,
    round(sum(hr.bad_debt)::numeric / nullif(sum(hr.total_revenues),0), 4) AS bad_debt_share,
    count(*) FILTER (WHERE hr.medicaid_inpatient_days IS NULL) AS hospitals_missing_medicaid_days,
    count(*) FILTER (WHERE hr.uncompensated_care IS NULL) AS hospitals_missing_ucc
  FROM hr JOIN x USING (ccn) GROUP BY 1,2),
s AS (
  SELECT 'ALL_HOSPITALS_AGGREGATE' AS ticker, 'sector' AS entity_class, 'All cost-report filers, FY2024, sums' AS operator, count(*) AS hospitals,
    round(sum(total_revenues)/1e9, 2),
    round(sum(medicaid_inpatient_days)::numeric / nullif(sum(total_inpatient_days),0), 4),
    round(sum(uncompensated_care)::numeric / nullif(sum(total_revenues),0), 4),
    round(sum(bad_debt)::numeric / nullif(sum(total_revenues),0), 4),
    count(*) FILTER (WHERE medicaid_inpatient_days IS NULL), count(*) FILTER (WHERE uncompensated_care IS NULL)
  FROM hr
  UNION ALL
  SELECT 'ALL_HOSPITALS_MEDIAN', 'sector', 'All cost-report filers, FY2024, median of per-hospital shares', count(*),
    NULL,
    round((percentile_cont(0.5) WITHIN GROUP (ORDER BY medicaid_inpatient_days::numeric / total_inpatient_days) FILTER (WHERE total_inpatient_days > 0 AND medicaid_inpatient_days IS NOT NULL))::numeric, 4),
    round((percentile_cont(0.5) WITHIN GROUP (ORDER BY uncompensated_care::numeric / total_revenues) FILTER (WHERE total_revenues > 0 AND uncompensated_care IS NOT NULL))::numeric, 4),
    round((percentile_cont(0.5) WITHIN GROUP (ORDER BY bad_debt::numeric / total_revenues) FILTER (WHERE total_revenues > 0 AND bad_debt IS NOT NULL))::numeric, 4),
    count(*) FILTER (WHERE medicaid_inpatient_days IS NULL), count(*) FILTER (WHERE uncompensated_care IS NULL)
  FROM hr)
SELECT * FROM (SELECT * FROM t UNION ALL SELECT * FROM s) u ORDER BY (entity_class = 'sector'), hospitals DESC;

Query C. Column population, FY2023 and FY2024.

SELECT fy_end_year, count(*) AS rows,
  count(medicaid_inpatient_days) AS medicaid_days_nonnull,
  count(medicaid_charges) AS medicaid_charges_nonnull,
  count(medicaid_costs) AS medicaid_costs_nonnull,
  count(uncompensated_care) AS ucc_nonnull,
  count(bad_debt) AS bad_debt_nonnull,
  count(*) FILTER (WHERE control_type ~ '^[0-9]+$') AS control_type_numeric
FROM hcris_hospital_reports WHERE fy_end_year IN (2023, 2024) GROUP BY 1 ORDER BY 1;

Result: FY2023 6,107 rows; Medicaid days 5,055; Medicaid charges 539; Medicaid costs 0; uncompensated care 4,556; bad debt 5,500; numeric control type 5,963. FY2024 6,134 rows; 5,057; 0; 0; 4,564; 5,186; 5,859.

Query D. HCA facility spread, FY2024.

WITH x AS (SELECT DISTINCT ccn FROM provider_operator_crosswalk WHERE ticker = 'HCA'),
hr AS (
  SELECT * FROM (
    SELECT h.*, row_number() OVER (PARTITION BY ccn ORDER BY fy_end DESC, ingested_at DESC) AS rn
    FROM hcris_hospital_reports h WHERE fy_end_year = 2024 AND ccn IN (SELECT ccn FROM x)) s WHERE rn = 1
    AND total_inpatient_days > 0 AND medicaid_inpatient_days IS NOT NULL),
r AS (
  SELECT ccn, provider_name, state, total_inpatient_days, medicaid_inpatient_days,
    round(medicaid_inpatient_days::numeric/total_inpatient_days, 4) AS medicaid_days_share,
    round(uncompensated_care::numeric/nullif(total_revenues,0), 4) AS ucc_share,
    round(total_revenues/1e6, 1) AS total_revenues_musd,
    rank() OVER (ORDER BY medicaid_inpatient_days::numeric/total_inpatient_days DESC) AS rk_desc,
    rank() OVER (ORDER BY medicaid_inpatient_days::numeric/total_inpatient_days ASC) AS rk_asc,
    count(*) OVER () AS n
  FROM hr)
SELECT CASE WHEN rk_desc <= 5 THEN 'top' ELSE 'bottom' END AS bucket, ccn, provider_name, state,
       total_inpatient_days, medicaid_inpatient_days, medicaid_days_share, ucc_share, total_revenues_musd, n
FROM r WHERE rk_desc <= 5 OR rk_asc <= 5 ORDER BY medicaid_days_share DESC;