# Age structure and US overdose mortality, 1999–2016

Age adjustment changes the national trend very little in this historical CDC/NCHS series. The crude drug-overdose death rate increased from **6.0382 to 19.6925 per 100,000** between 1999 and 2016; the published age-adjusted rate increased from **6.0570 to 19.7851**. Both more than tripled. A separate decomposition using eight broad age groups indicates that shifts between those groups slightly offset, rather than explained, the increase.

| Measure | 1999 | 2016 | Change |
|---|---:|---:|---:|
| Deaths | 16,849 | 63,632 | +46,783 |
| Crude rate per 100,000 | 6.0382 | 19.6925 | +226.13% |
| Age-adjusted rate per 100,000 | 6.0570 | 19.7851 | +226.65% |

These conclusions apply to **1999–2016**, not the more recent epidemic.

## Sources and scope

The primary source is [NCHS — Drug Poisoning Mortality by State: United States](https://data.cdc.gov/d/xbxb-epbu), dataset `xbxb-epbu`. Despite its title, it contains national demographic rows. The analysis retains United States, Both Sexes, All Races-All Origins, and all 18 available years. It uses 162 rows: one all-age row and eight age-group rows per year. No state, sex, race, or drug-specific comparisons are made.

The [CDC metadata](https://data.cdc.gov/api/views/xbxb-epbu.json) define overdose by underlying-cause ICD-10 codes **X40–X44, X60–X64, X85, Y10–Y14**, covering unintentional, suicide, homicide, and undetermined intent. The definition is consistent across this period. This is the historical annual NVSS mortality table, not the separately identified provisional rolling 12-month overdose dashboard. We use this archived data vintage as published, rather than claim it incorporates every later revision.

Metadata specify direct age adjustment to the **2000 US standard population**. They also state that population denominators for 2011–2016 are postcensal estimates based on the 2010 census; census years use enumerated populations and earlier noncensus years use revised intercensal estimates. That denominator history is retained as a comparability limitation.

The bundle includes exact response snapshots, metadata, retrieval URLs and query, access timestamp, SHA-256 checksums, and package versions. A CDC report HTML page denied access during preparation; it was not used as evidence. All findings here can be checked against the accessible CDC dataset and its preserved metadata.

## What adjustment changes

A crude rate is deaths divided by the population actually living in that year. It describes the observed population burden per person. An age-adjusted rate weights age-specific rates using a fixed standard age distribution. It is a comparative index, not the observed death count divided by the actual population, and multiplying it by the actual population would not recover deaths.

The annual adjusted and crude rates differ by no more than **1.025% of the crude rate**. The largest absolute difference is **0.1236 per 100,000**, in 2009, when the adjusted rate is lower. In 2016 adjustment raises the rate by 0.0926 per 100,000. Adjustment need not always raise or always lower overdose mortality: the result depends on how the population weights align with the age-specific mortality pattern.

Both measures show the same direction of change in every year. They show slow growth in 2007–2009, a small numerical decline in 2012, and a large increase in 2015–2016: **20.78% crude versus 21.44% adjusted** for that last interval. These are descriptive changes, not independently tested turning points. Adjustment changes the full-period percentage increase by only **0.52 percentage points**.

A small crude–adjusted gap alone does not prove that demographic change has no effect. That comparison uses a particular standard population, and positive and negative age-group contributions can cancel. We therefore also examined changing population shares directly.

## Age-composition accounting

For age group i and year t, let p_it be its population share and r_it its death rate per 100,000. The known-age crude rate is the sum of p_it × r_it. We used the groups 0–14, 15–24, 25–34, 35–44, 45–54, 55–64, 65–74, and 75+.

For 1999 (0) to 2016 (1), the symmetric Kitagawa identity separates:

- **Composition component:** sum of (p_i1 − p_i0) × (r_i1 + r_i0) / 2.
- **Within-age rate component:** sum of (r_i1 − r_i0) × (p_i1 + p_i0) / 2.

A separate reconciliation residual accounts for all-age deaths not allocated to the displayed age groups. The metadata do not explicitly label these deaths as unknown age, so we call them *unallocated-age residuals*.

| Component | Change per 100,000 |
|---|---:|
| Within-age rate changes | +13.895354 |
| Changes in broad age-group shares | −0.238376 |
| Unallocated-age residual change | −0.002639 |
| Total crude-rate change, calculated from counts | +13.654338 |

The components sum to the exact count-derived change within numerical precision. Published crude rates are rounded to four decimal places, so their difference is 13.6543.

The net composition component offsets about **1.75% of the observed net increase**. This signed percentage is an arithmetic comparison, not a causal attributable fraction. Within-age rate increases exceed 100% of the net change because the other components are negative.

There is substantial cancellation within the composition component: the declining share aged 35–44 contributes about **−0.8895**, while the growing share aged 55–64 contributes **+0.6425** per 100,000. Thus, a small national net effect does not mean all demographic contributions are small.

Every one of the eight broad age-specific rates increased between the endpoints. Holding the 1999 population shares fixed gives a rate increase of **13.82798** per 100,000; holding the 2016 shares fixed gives **13.96273**. Both support the conclusion that the rise persists under fixed broad age composition. These curves exclude the small unallocated-age residual and are **not reproductions of the official 2000-standard age-adjusted series**.

## Checks and limitations

There are no duplicate year–age cells or missing deaths, populations, or crude rates. All populations are positive, and age-group populations sum exactly to each all-age population. Recalculated crude rates agree with published rates within 0.00005 per 100,000, consistent with rounding.

Age-group deaths fall short of all-age deaths by 2–16 annually. Those residuals are retained in the annual table and decomposition, rather than silently deleted. The endpoint residual rates are approximately 0.00573 and 0.00309 per 100,000. All-age published confidence limits are retained in the CSV; the figure shows point estimates.

Crude and adjusted rates use the same deaths and are correlated. We did not apply independent-rate tests to their difference or infer statistical significance from overlapping confidence intervals. No decomposition confidence interval or formal trend-break model was estimated. Death-registration statistics remain subject to classification error, reporting practices, denominator uncertainty, and stochastic variation; the dataset specifically warns about unresolved or misclassified deaths in some state-years.

Broad age bands leave within-band aging inside the within-age rate component. That component therefore should not be interpreted as pure changes in individual risk. Finer ages could alter the decomposition. The symmetric decomposition is also a chosen endpoint accounting convention, not a uniquely identified causal effect. The published standardization and broad-band decomposition answer related but different questions.

These aggregate data cannot establish whether fentanyl, prescribing, treatment access, policies, birth-cohort effects, or other mechanisms caused the increase. They do support a narrower conclusion: **the national rise during 1999–2016 remains very large after age adjustment, and shifts between the available age groups do not explain it**.

## Reproduce and inspect

All computation ran through native Notebook using the existing enabled local Python runtime and installed dependencies. Nothing was installed, no environment was created, and the application was not modified. Recorded versions: Python 3.12.3, pandas 3.0.5, NumPy 2.4.6, Matplotlib 3.8.4.

Extract `overdose_reproducibility.zip`. From that folder, with those packages already available, run:

```text
python analysis.py --input . --output rerun
```

Or use a native Python Notebook cell:

```python
from pathlib import Path
ns = {"__name__": "analysis_module"}
exec(compile(Path("analysis.py").read_text(encoding="utf-8"), "analysis.py", "exec"), ns)
ns["analyze"](".", "rerun")
```

This offline analysis reads the preserved source snapshot, verifies its checksum, validates cells, recomputes all tables, and renders PNG/PDF figures. An independent second execution against the saved inputs produced byte-identical CSV tables and results JSON. Binary PDF byte identity is not required because file metadata can vary.

The source manifest records the exact CDC query for online refresh. Refreshing creates a new data vintage and requires updating the preserved source snapshot and corresponding checksum; preserve the original bundle for comparison.

Files in the bundle include raw national JSON, source metadata JSON, source manifest, `national_extract.csv`, `annual_comparison.csv`, `age_decomposition.csv`, `results.json`, the script, this report, and PNG/PDF figures. Annual fixed-share rates and residuals are in the annual table; component formulas are implemented directly in the script.

Figure description: Panel A shows nearly overlapping crude and official age-adjusted rates rising from about 6 to about 20 per 100,000. Panel B magnifies their small signed difference on its own labelled scale. Panel C compares observed crude rates with two fixed broad-group population distributions. Panel D shows positive within-age contributions in every group and partly offsetting age-share contributions. Lines are unsmoothed; line styles and hatching supplement color. The PNG is 2400 × 1600 pixels; the PDF retains vector graphics.
