Reachability swept first: yes, and badly the first time — the sweep
covered OWID only, concluded "no net-migration series exists", and built the
sheet on a derived residual. The World Bank connector already in this repo
serves the published series. See Open questions.
Vintage checked: yes. Births/deaths are UN WPP (2024), lastUpdated
2024-07-12. population is NOT purely WPP — it is a HYDE (2023) /
Gapminder (2022) / UN WPP (2024) splice, lastUpdated 2024-07-15,
nextUpdate 2026-12-15. Net migration is World Bank SM.POP.NETM, lastupdated 2026-07-13.
Segment: Births, deaths, and the door
- Source theme(s): Batch 54 #3
- Spine role: main story
- The framing people carry: that immigration is one contributor to population growth among several, arguing at the margin against births.
- Hypothesis (from the bank): natural increase is falling through zero in most high-income countries; net migration is becoming "not a contributor to growth but the entire whole of it" in a growing list of countries, with crossover dates clustering in the 2010s and 2020s.
- Verdict: QUALIFIED. The mechanism is confirmed and unambiguous in named large countries — Germany grew by 462,006 people in 2023 while registering 314,889 more deaths than births, and the World Bank puts its net migration at +609,553. But the bank's "growing list" is not safely countable, because the producers disagree about population itself. Poland's 2023 population rises by 377,113 in OWID and falls by 134,396 in the World Bank — a 2.08 million difference in level and opposite directions — so Poland's membership in any such count is a choice of source, not a fact. Lead with the mechanism and a few named countries. Never lead with a count.
The numbers (every row sourced — no exceptions)
| Claim | Value | Series / dataset | Source (named, dated) | Tier | Confidence |
|---|---|---|---|---|---|
| Germany 2023, natural increase | −314,889 | births − deaths | UN WPP (2024) via OWID; lastUpdated 2024-07-12 |
A | high |
| Germany 2023, population change | +462,006 | population |
HYDE/Gapminder/UN WPP via OWID; lastUpdated 2024-07-15 |
A | high |
| Germany 2023, net migration (published) | +609,553 | SM.POP.NETM@DEU |
World Bank, via worldbank-fetch.ts; 66 points |
A | high |
| Japan 2023 | nat. increase −774,547; migration +175,003; population still falls | as above | as above | A | high |
| Italy 2023 | nat. increase −278,817; migration +150,189; population still falls | as above | as above | A | high |
| Australia 2023 | nat. increase +120,413; migration +140,232 | as above | as above | A | high |
| Poland 2023 — the producer trap | OWID population +377,113, World Bank −134,396 (levels 2.08M apart, opposite directions) | population vs SP.POP.TOTL@POL |
OWID vs World Bank | A | high |
| Poland 2023, net migration | published −7,824; implied −40,004 on WB population, +471,505 on OWID population | SM.POP.NETM@POL |
World Bank; lastupdated 2026-07-13 |
A | high |
| World net migration, every year | exactly 0 | SM.POP.NETM@WLD |
World Bank | A | high |
| China 2023, net migration | −567,724 (net emigration) | SM.POP.NETM@CHN |
World Bank | A | high |
| Observed data range, births/deaths | 1950–2023 (2024–2100 projected, separate columns) | number-of-births-per-year, number-of-deaths-per-year |
UN WPP (2024) | A | high |
| Countries growing while natural increase is negative | 2000 5 · 2010 6 · 2019 16 · 2021 19 · 2022 25 · 2023 25 | derived from births, deaths, population | as above | A | low — do not publish, see Open questions |
| Same, population > 1M | 2000 4 · 2010 3 · 2015 5 · 2019 10 · 2021 7 · 2022 16 · 2023 17 | derived | as above | A | low — non-monotonic in both directions |
The texture (what narrative flattens)
- Three regimes, not one. Germany: natural increase negative, migration more than offsets it, population grows. Japan and Italy: natural increase negative, migration real and substantial, population still falls. Australia: natural increase still positive, migration the larger half. The public argument treats these as one question.
- A stable headline can hide two large opposed flows. Hungary's population moved +2,157 in 2023 on a natural increase of −42,691.
- The crossing is set decades in advance. Natural increase turns negative when a cohort born under higher fertility reaches the age of dying, which is why the dates cluster and why they were foreseeable.
Datoid artifact (Tier-A only)
- Net migration is ingestable and is NOT an OWID series.
SM.POP.NETM@<ISO3>through the existing World Bank connector — verified by runningfetchIndicatorSeries, 66 points per country,lastupdated2026-07-13 (two years newer than the OWID snapshots, so the producer gaps are vintage gaps too). This is exactly the hedge that connector was built to be. - DO NOT MIX PRODUCERS FOR POPULATION AND MIGRATION. If migration comes from
the World Bank, population must too (
SP.POP.TOTL@<ISO3>), or the panel asserts a decomposition its own series contradict. Nothing in the codebase will stop you:composition.tshas no production callers, a dashboard panel renders throughChartFrame → DataChart → Chart.tswithout computing shares, andcompositionSharesrefuses negative components anyway — which this decomposition has. The discipline is editorial, not enforced. - "One producer throughout" is NOT achievable, and the reason is recorded in
this repo.
seed-worldbank-maternal.tsnotes that the World Bank publishes crude birth rate, not counts, and that deriving counts would mean pop × CBR, "a computed series we have no mechanism for". So births and deaths must come from OWID whatever population does. The realistic rule is narrower: keep population and migration on one producer, and treat the vital-statistics leg as a documented cross-source join. - Births and deaths: use the STANDALONE slugs,
number-of-births-per-yearandnumber-of-deaths-per-year. Verified by running it: the four-columnbirths-and-deaths-projected-to-2100grapher returns deaths only, becauseparseOwidCsvreadscols[3]. The standalone slugs put the observed value at index 3 with projections in a column the connector correctly ignores. - THREE DIVISOR TRAPS, all #75's defect class.
(1)
VALUE_DIVISORScarriesnumber-of-births-per-year: 1e6and no deaths entry — two series that must share an axis would sit a million-fold apart. (2)VALUE_DIVISORSis slug-keyed by design, so anypopulation@<country>row is forced to the World-scale 1e9. Germany 2023 would store as births 0.719249 (1e6), deaths 1,034,138 (no divisor) and population 0.0845 (1e9) — 1,437,802× between births and deaths, and ~12.2 million× between deaths and population (the exact ratio depends on unrounded population), with population rendering below its own birth line. (3) The World Bank connector has the same asymmetry on the pair this sheet recommends: itsVALUE_DIVISORScarriesSP.POP.TOTL: 1e9and noSM.POP.NETMentry, so population and migration would sit ~7.2 million apart on one axis. All three must be settled before a panel is built. populationis seeded World-only (bare slug,prisma/seed.ts); the per-country rows this story needs do not exist. Fournumber-of-births-per-year@<income group>series exist only from a draft seed script that is in neitherprisma/seed.tsnor the prod seed endpoint — so they are absent on prod and on a fresh bootstrap. Check, but do not assume.
Story justification (decide here — do NOT defer)
- Does the argument have a reveal that needs sequencing? YES — BUILD.
- Because: the reveal is the decomposition itself. The reader must first see a population line doing something unremarkable — Germany growing, Hungary flat — and only then see it split into two large opposed flows. A stacked chart from the start has no reveal, because the composition is the first thing visible.
The questions this raises (and whether we can answer them)
Stage 1 rule 6, added 2026-09-23. Everything above verifies a hypothesis; this names what a READER asks next and forces the decision before Stage 2 runs — fetch it, attribute it, or declare it open. Every slug named here was swept for reachability first.
- Is the turn driven by fewer births or by more deaths? — FETCHABLE, and
the arithmetic is subtraction — but it is NOT free. Both series are named
above, and Datoid artifact records that
VALUE_DIVISORScarriesnumber-of-births-per-year: 1e6and no deaths entry, so the stored values sit a million-fold apart and subtracting them yields nonsense. The divisor asymmetry must be settled before this is computed, let alone drawn. A draft of this line called it "nearly free" forty lines above the trap that makes it costly. - What does the age structure look like after the crossing? — FETCHABLE.
median-age(swept 200) andage-dependency-ratio-old(200), both UN WPP via OWID — the same producer as the births and deaths, so this one widening adds no new cross-producer join. - Do the producers disagree about other countries, or only Poland? —
FETCHED, AND IT IS THE FINDING.
[verified 2026-09-24, local]across twenty countries, four disagree in the SIGN of the 2022→2023 population change — Poland (OWID +377,113, World Bank −134,396), Hungary (+2,157 / −12,888), Romania (−48,294 / +12,560) and South Korea (−33,771 / +40,050). The median level gap is 0.78% and the maximum 5.66% (Poland). Even where the signs agree the magnitudes do not: Germany is +462,006 against +109,460, a factor of four. So Poland is not an unlucky case to caveat — one country in five flips, and the refusal to publish a country count is the sheet's finding rather than its hedge. Say it that way. - Where do the migrants come from, and where do they go? — OPEN for us. Net migration is a single signed number per country and no connector we have carries bilateral flows.
- How long can migration offset natural decline? — ATTRIBUTABLE, not derivable. UN WPP publishes its own projections; computing our own here would be a forecast wearing an identity's clothes.
Open questions / where I'm guessing
- I CONCLUDED A SERIES DID NOT EXIST AFTER SWEEPING ONE SOURCE. Seven OWID
slugs 404'd and this sheet said "there is no net-migration series to ingest".
The World Bank connector — present in this repo, and documented as the vintage
hedge for exactly these UN-sourced indicators — serves
SM.POP.NETMfor 66 years per country. A search is evidence about the search. The whole derivation below existed only because of that error. - THE POLAND INVERSION IS A CROSS-PRODUCER JOIN ERROR, not a broken identity — and an earlier draft of this sheet said otherwise in its verdict. Published migration −7,824 against an implied +471,505 looked like a 479,000-person contradiction. It is not: that residual was computed from OWID population against World Bank migration. On the World Bank's own population the implied figure is −40,004 — same sign, same order. The inversion disappears when one producer is used throughout, and the real finding is that OWID has Poland's 2023 population rising by 377,113 while the World Bank has it falling by 134,396, levels 2.08M apart. Germany shows the same disagreement more mildly (ΔPop +462,006 against +109,460). Displaced Ukrainians are a plausible cause and are NOT established; do not assert it.
- So the country counts are a statement about ONE producer's population series. The criterion (natural increase < 0, population growth > 0) uses only births, deaths and population, so it is internally sound — but Poland qualifies on OWID and does not on the World Bank, which makes membership a choice of source. Recompute on a single producer end to end before any count is published, and expect the answer to move.
- The count is contaminated three further ways. Microstates — Niue, San Marino, Jersey, Guernsey, Bermuda, Aruba flip on a few hundred people. Non-monotonicity — the >1M count falls 10 → 7 between 2019 and 2021, and also 4 → 3 between 2000 and 2010, so the dip is not diagnostic of COVID as an earlier draft claimed. The invasion of Ukraine — the 2022 step from 19 to 25 is Ukraine-adjacent countries, though per the Poland row the mechanism is not what it appears.
- The joiner lists do not reconcile with the totals and were reported as though they did: eight named joiners against a net +6 between 2021 and 2022, because countries leave the set as well as enter it. Any year-on-year narrative needs the leavers too.
- The World = exactly 0 check is weaker than it looks. It holds by construction in the World Bank's own accounting, so it confirms internal consistency and not that country figures are right.
- The bank's Basis
I(identity) is NOT falsified — but nor is it verified, and this sheet has now claimed both. Draft one called it falsified on the Poland inversion; draft two said "the identity holds within a producer". A within-producer test is not possible here, because the World Bank publishes birth and death rates rather than counts, so natural increase is OWID whatever else is. Every check available is a cross-source join. On World Bank population with OWID natural increase, Germany implies +424,349 against a published +609,553 — a 30% gap in the best case available. Treat the identity as true in principle and unverified in these series. - The bank's fourth claim — the crossover being "almost entirely absent from political discourse" — is NOT tested and is not testable on this data. It is Tier B, needing media or parliamentary sources.
- Crossover dates were not computed per country. The clustering hypothesis is consistent with the trajectory; no country's crossing year is established.
natural-population-growthis a RATE, not a count — swept and set aside. Recorded because the name invites the same errorco2-intensityproduced on the previous sheet.