Skip to content

Use CMS Medicare spending per enrollee for the Medicare per capita cost - #10107

Merged
MaxGhenis merged 5 commits into
mainfrom
medicare-per-enrollee-cms
Oct 12, 2026
Merged

MaxGhenis merged 5 commits into
mainfrom
medicare-per-enrollee-cms

Conversation

@MaxGhenis

@MaxGhenis MaxGhenis commented Oct 11, 2026 •

Copy link
Copy Markdown
Contributor

Summary

calibration.gov.hhs.medicare.per_capita_cost held KFF's 2021 traditional Medicare figure ($11,080, which pe-us backdating also applied to 2015-2020) and an unsourced 2025 "estimate" of $14,500 with no uprating, so every year from 2025 to 2100 read $14,500. This PR sets it to CMS's published Medicare spending per enrollee from the National Health Expenditure (NHE) projections, Table 17: historical for 2013-2024, projected for 2025-2034, and extended to 2100 in uprating_extensions.py.

Year Before After
2015 11,080 11,929
2021 11,080 14,293
2024 11,080 16,779
2025 14,500 17,751
2026 14,500 18,983
2027 14,500 20,096
2030 14,500 23,789
2034 14,500 30,129
2050 14,500 70,189
2100 14,500 986,356

Which definition, and why

The parameter feeds three variables:

  • medicare_gross_cost returns it for every medicare_enrolled person; it is in CBO household income (cbo_social_insurance_benefits).
  • medicare_cost subtracts the person's Part A premium and gross Part B premium, floored at zero; it is a US program statistic in policyengine.py.
  • qmb_cost_sharing pays QMB enrollees 20% of it a year, in monthly twelfths. It feeds msp_cost, which feeds household_health_benefits, and its federal and state shares, which feed federal_benefit_cost and state_benefit_cost.

medicare_enrolled is "enrolled in Medicare (Part A and/or Part B)". No variable splits traditional Medicare from Medicare Advantage (no variable mentions Medicare Advantage). So the parameter has to be the average gross Medicare spending over all Part A and/or B enrollees. NHE Table 17 measures that:

  1. Who is counted. NHE Medicare enrollment counts Part A and/or B enrollees in person-years, with the territories removed (NHEA methodology paper, file page 34).
  2. What is counted. NHE Medicare spending covers Parts A, B, C (Medicare Advantage) and D (page 15). As program spending, it also includes federal administration and the non-medical expenditures of Part C and D private plans (page 23). Table 17's Medicare spending row equals Table 03's Medicare source of funds in every year Table 03 covers, 2018 to 2034 (for example, $1,118.0 billion in 2024).
  3. Premiums. The spending is gross of premiums: the sponsor analysis counts SMI premiums as household spending that finances Medicare (page 30). That fits medicare_cost subtracting premiums and medicare_gross_cost not subtracting them.
  4. Geography. Spending and enrollment both cover the 50 states and DC, as the CPS-based data do.
  5. Projection basis. CMS generated the NHE Medicare spending and enrollment projections for the 2026 Medicare Trustees Report (projections methodology, file pages 6-7).

Alternatives considered and rejected:

  • Traditional Medicare per traditional Medicare enrollee (the old KFF value). It leaves out Medicare Advantage, whose payments were "roughly 52 percent of total A and B benefit costs in 2025" (Trustees Report, file page 18). Medicare Advantage enrollees are medicare_enrolled too.
  • Trustees Report Table V.D1 "Total" per beneficiary cost (file page 210). Footnote 2 says it is "the sum of the HI and SMI per beneficiary costs". So it values someone enrolled in every Part, while Table II.B1 counts 63.4 million Part B and 56.8 million Part D enrollees among 69.3 million. It also includes the territories. It runs 5.6% to 7.6% above Table 17 in every year from 2015 to 2034, and that gap is now a test.
  • NHE personal health care only (Table 05 Medicare). It drops administration and the plans' non-medical expenditures that Medicare pays on enrollees' behalf ($1,045.4 billion against $1,118.0 billion in 2024).

Two consequences are handled in separate PRs:

Extension to 2100

extend_parameter_values(..., last_projected_year=2034, growth_years=(2031, 2032)) grows each year from 2035 to 2100 at 26,552 / 25,185 (5.43%) and then holds the 2100 value. It does not use the 2033-2034 rate (6.55%). Sequestration cuts Medicare expenditures 2% through August 31, 2033 (Trustees Report, file page 209), and its end lifts 2033 and 2034 growth. In the Trustees' own Table V.D1, per beneficiary growth runs 6.5% in 2033 and 6.6% in 2034, then falls to 5.4% in 2035. The extension's 2035 value ($31,764) is within 0.05% of 2034 grown at the Trustees' 2034-2035 rate ($31,750). The Trustees' 2050-2100 assumption is slower, 3.7% a year excluding demographic effects (Table II.C1). #10119 adds a glide to the Trustees' long-range rates. It wires the out-of-pocket and employer premium series now, and defines the knots for this series but wires them in a follow-up once this PR merges.

Household-level changes (YAML tests)

  • medicare_cost, 2025, premium-free Part A, standard Part B: $12,280 to $15,531 ($17,751 - $2,220).
  • qmb_cost_sharing, January 2026: $241.67 to $316.38 ($18,983 / 12 x 20%). A QMB-only enrollee's msp_cost in 2026 goes from $5,334.80 to $6,231.40.
  • The CBO household income example (2025) rises $3,251, the change in medicare_gross_cost.

Microsim impact

Real runs on the default dataset (hf://datasets/policyengine/populace-us/populace_us_2024.h5@populace-us-2024-spm-20260909). The base is upstream/main 23285ce622; the PR snapshot is cdfe759d6f. Its parameter values and every consumer match the current head. The head differs only in comment and reference edits to the two changed parameter files and in taxsim_v17.py, an unrelated output variable that the main merge brought in. Both ran under the hub heavy lock, one run per year and side: four runs, 15.7 to 17.6 minutes of simulation each (20.6 to 26.5 minutes of process time with imports). Totals are weighted sums.

2027 base 2027 PR Change 2034 base 2034 PR Change
medicare_gross_cost $852.6B $1,181.6B +$329.0B $873.9B $1,815.8B +$941.9B
medicare_cost $684.2B $1,013.2B +$329.0B $692.7B $1,634.7B +$941.9B
msp_cost $11.91B $13.69B +$1.77B $11.64B $16.77B +$5.13B
msp_federal_cost $7.57B $8.61B +$1.05B $7.49B $10.49B +$3.00B
msp_state_cost $4.35B $5.07B +$0.72B $4.15B $6.28B +$2.13B
healthcare_benefit_value $964.2B $965.9B +$1.77B $982.2B $987.4B +$5.13B
cbo_household_income $23,475B $23,804B +$329.0B $29,838B $30,780B +$941.9B
household_net_income $17,806B $17,806B 0 $22,386B $22,386B 0
SPM poverty rate 14.16% 14.16% 0 14.77% 14.77% 0

What moves and why:

  • Medicare cost. It changes for each of the 24,147 enrolled person records (58.8M weighted in 2027, 60.3M in 2034), and only upward. Each moves by the change in the series, $5,596 in 2027 and $15,629 in 2034, to the cent on every record, so the zero floor never binds.
  • MSP cost. It moves for 1.58M (2027) and 1.64M (2034) weighted QMB-only enrollees, by 20% of the series change, $1,119.20 and $3,125.80 a year, to the cent on every record.
  • CBO household income rises by the same $329.0B and $941.9B.
  • household_health_benefits stays zero. The default include_health_benefits_in_net_income is off.
  • SPM resources, household_net_income and SPM poverty change for no record in either year: these values do not enter them.

The modeled Medicare totals are 83% (2027) and 77% (2034) of NHE Medicare spending ($1,422.7B and $2,354.3B). Those ratios agree, within the published rounding, with the ratios of modeled to CMS enrollment: 58.8M against 70.8M, and 60.3M against 78.1M. So the per-enrollee value now matches CMS, and the remaining gap is the dataset's enrollee count, tracked in PolicyEngine/microcosm#231.

Driver, outputs, and the compare and poverty JSONs are in ~/reviews/medicare-per-capita-cost-2026-10/impact/ on the session host.

Invariants (tested)

policyengine_us/tests/core/test_medicare_per_capita_cost.py:

  1. Transcription. All 22 values equal Table 17's published figures. Each one also lies within rounding of the same table's spending over enrollment, so a single mistyped number in any of the three rows fails.
  2. Cross-source level. The Trustees' V.D1 total per beneficiary cost lies between 1.05 and 1.08 times the series in every year from 2015 to 2034.
  3. Order (exhaustive; Hypothesis after 2100). The series is positive and strictly increasing in every adjacent pair of years from 2013 to 2100, and constant after 2100.
  4. Extension (exhaustive, differential). Each year from 2035 to 2100 equals the closed form 30,129 x (26,552 / 25,185)^(year - 2034), which checks the iterative extension. The 2035 value is within 0.1% of the Trustees' 2035 growth.
  5. Calendar years (Hypothesis). Every date in a year reads the January 1 value.
  6. Consumers (Hypothesis over years and premiums).
    • medicare_gross_cost equals the series.
    • medicare_cost equals max(series - Part A premium - Part B premium, 0) and never exceeds medicare_gross_cost.
    • A non-enrolled person gets zero.
    • Monthly qmb_cost_sharing equals the series / 12 x the QMB rate.

Mutation check: dropping growth_years fails all 66 closed-form cases and the Trustees-2035 test.

The shared test_all_uprating_factors_extend_to_2100 now covers this series too.

Sources

Source URL Retrieved sha256
NHE projections tables 2025-2034 (Last-Modified 2026-09-03), Tables 03, 05, 17 https://www.cms.gov/files/zip/nhe-projections-tables.zip 2026-10-11 264f822618a5e1829138aea57cc6c8bf45bbaf072a72898fef5547f7ece6cd70
NHEA methodology paper, 2024 https://www.cms.gov/files/document/definitions-sources-methods.pdf 2026-10-11 9c5755666847a78103016f04da937326744071a9a6736f4e77e91ce9e7af8629
NHE projections methodology, June 24, 2026 https://www.cms.gov/research-statistics-data-and-systems/statistics-trends-and-reports/nationalhealthexpenddata/downloads/projectionsmethodology.pdf 2026-10-11 ce62fe2c236cc96ce287027784b141584ddf39e62c5fd8ddc3e771a014944817
2026 Medicare Trustees Report https://www.cms.gov/oact/tr/2026 2026-10-11 ffa56b9137006872300b0346149eae1613d09a172b6ba118aad48e66dfc48fa8

Interactions

#10085 and #10103 (Medicare premium projections) do not touch this parameter. git merge-tree is clean against main and against #10084, #10085, #10097, #10103 and #9621, which also edit uprating_extensions.py. #10111, then #10118, then #10126 are stacked on this PR.

Tests run

  • CI on the current head (b120f93): see the checks tab. Run 38177071018 had passed PR validation and packaging when the US + core hub cancelled the rest at 23:27Z on 2026-10-11 to free shared runners; the hub re-runs the cancelled jobs. Before the main merge, run 38159915527 at 33a94b4 passed every baseline, contrib, partner, microsimulation and quick-feedback check. The one failure there, the il_aabd_expense_exemption_person person-adds ratchet, was failing on main and was fixed by Drop the fixed Illinois AABD entry from the person-adds ratchet #10092, which the merge brings in.
  • Local: policyengine_us/tests/core/test_medicare_per_capita_cost.py and tests/policy/baseline/parameters/test_uprating_extensions.py, 250 passed.
  • Local: gov/hhs/medicare and household YAML directories plus the CO and MA integrations: 852 of 853 passed. The one failure, federal_and_state_benefit_cost.yaml case 6, still expected the old QMB cost; it was updated in 33a94b4 and rerun (6 passed). The basic health program, WA cascade care, and Tlaib integration files, which also output affected variables, passed (35).
  • Mutation check described above.
  • Independent review (GPT-6.1 Sol, Subfleet review/hard): APPROVE. Its should-fixes are applied in b120f93: one NHEA reference at the canonical URL, page cites, exhaustive year-domain tests. A delta review at b120f93 (same reviewer tier) also returned APPROVE. It recomputed every figure in the microsim section from the saved arrays; its remaining points were wording in this description, now corrected.

axiom: n/a: calibration spending series (CMS NHE data), not a statutory provision

🤖 Generated with Claude Code

MaxGhenis and others added 2 commits October 11, 2026 12:59
Replace KFF's 2021 traditional-Medicare figure and an unsourced $14,500
2025 estimate (held flat for every later year) with CMS National Health
Expenditure Table 17's Medicare spending per enrollee: historical
2013-2024, projected 2025-2034, extended to 2100 at the 2031-2032 rate
so the end of sequestration in 2033 does not compound.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Transcription checks against NHE Table 17 (and its spending over
enrollment), a cross-source level check against the Trustees Report's
per beneficiary cost, Hypothesis properties for order, the 2035-2100
closed form and calendar-year steps, and identities for
medicare_gross_cost, medicare_cost and qmb_cost_sharing. Existing
expectations move from $14,500/$11,080 to the CMS values.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@MaxGhenis
MaxGhenis marked this pull request as ready for review October 11, 2026 17:27
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Merge the two NHEA methodology entries into one reference (#page
  15,23,30,34) at the canonical URL the old one redirects to.
- Cite the projections methodology's file pages 6-7 and the Trustees
  Report's all-Medicare sequestration statement (file page 209).
- Check order and the 2035-2100 closed form for every year instead of
  sampling, and drop Hypothesis deadlines on the remaining lookups.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@MaxGhenis

Copy link
Copy Markdown
Contributor Author

The CI run on this pull request was cancelled at 23:27Z on 2026-10-11 to free the organization's shared GitHub runners for an urgent fix in another repository. The US + core hub will re-run it automatically (cancelled jobs only; jobs that had passed are kept). Nothing in this pull request changed. Please don't push or reopen just to restart CI.

@MaxGhenis

Copy link
Copy Markdown
Contributor Author

Hand-off to the US + core hub (session local_54aa9ecf-6420-47f6-a870-c16ea67abf92). Nothing on this PR is waiting on its author session; what remains is CI and merge order.

🤖 Generated with Claude Code

@MaxGhenis
MaxGhenis merged commit bff00e5 into main Oct 12, 2026
28 of 52 checks passed
@MaxGhenis

Copy link
Copy Markdown
Contributor Author

US + core hub merge audit, us#10107 at b120f939e50185ada9228c3b9a2ccae6e0c80cfe (squash): Medicare per capita cost from CMS National Health Expenditure spending per enrollee.

  • Reviews: independent GPT-6.1 Sol reviews, both APPROVE. Round 1 assessed the definition against four alternatives (traditional Medicare only, Trustees Table V.D1, personal health care only, Trustees total over enrollment) and found NHE spending per Part A and/or B enrollee right for a cost-to-government value. Round 2, a delta review at this head, recomputed every microsimulation figure from the saved arrays; its description findings are applied.
  • Gates checked live at merge:
    • gh pr checks exits 0;
    • the latest Pull request run at the head concluded success;
    • MERGEABLE;
    • not a draft;
    • no reviewer's latest review requests changes;
    • the semantic-overlap guard;
    • head pinned.
  • Impact (in the description, default dataset): Medicare gross cost and medicare_cost +$329.0B in 2027 and +$941.9B in 2034; MSP cost +$1.77B and +$5.13B; CBO household income rises by the Medicare change. Household net income, SPM resources and SPM poverty do not change.
  • Why no ruling was needed: the PR replaces a frozen, unsourced value with the CMS series the parameter cites; the hub treats it as a correction to the cited source.
  • Order: either order with Value QMB cost sharing at Medicaid's CMS-64 spending per QMB #10123. Subtract the expected Part D premium from medicare_cost #10111, Count Medicare net of premiums in CBO household income #10118 and Scale Medicare per-enrollee spending to enrollees outside nursing homes #10126 are stacked on it and retarget after this squash.
  • Axiom: n/a, as the description states (a calibration spending series, not a statutory provision).

@MaxGhenis
MaxGhenis deleted the medicare-per-enrollee-cms branch October 12, 2026 12:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant