Skip to content

Wikipedia pageview site went stale: prove it's the upstream AQS pipeline, not your cron, using dumps.wikimedia.org

When a site built on the Wikimedia pageviews API (wikimedia.org/api/rest_v1/metrics/pageviews/...) stops updating, the failure is usually upstream, and you can prove it in three curls before you touch the host.

Symptom

Static pages stop regenerating. Local logs show a clean, repeating error, e.g.:

E2026-08-16T06:15:15 - "fetch_traffic" - urllib.error.HTTPError('HTTP Error 404: Not Found')
S2026-08-16T06:15:15 - "get_wiki_info" - succeeded

Note get_wiki_info (MediaWiki action API) succeeds while fetch_traffic (AQS) 404s. Network and DNS are fine; only the analytics dataset is missing.

AQS returns a semantic 404 with a body that says so, not an error page:

{"detail":"The date(s) you used are valid, but we either do not have data for those date(s), or the project you asked for is not loaded yet","status":404}

Three-step triage

  1. Bisect the last good date on AQS, from two different networks (your laptop and the server) so you don't blame egress:
for d in 2026/08/13 2026/08/14 2026/08/15; do
  printf "%s -> " "$d"
  curl -sS -o /dev/null -w "%{http_code}\n" \
    "https://wikimedia.org/api/rest_v1/metrics/pageviews/top/en.wikipedia/all-access/$d"
done
  1. Check whether it's the top endpoint or the whole dataset. Hit aggregate and per-article for the same dates, and a second project (de.wikipedia). If all of them stop on the same day, it's the dataset load, not an endpoint bug.

  2. Check the dumps, which reveal which stage of the Wikimedia pipeline died — this is the step people skip:

    • Hourly: https://dumps.wikimedia.org/other/pageviews/YYYY/YYYY-MM/
    • Daily rollup: https://dumps.wikimedia.org/other/pageview_complete/YYYY/YYYY-MM/
curl -sS "https://dumps.wikimedia.org/other/pageview_complete/2026/2026-08/" \
  | grep -oE 'pageviews-202608[0-9]{2}-user' | sort -u | tail -5

Interpretation:

  • hourly current, daily rollup behind -> the daily aggregation/AQS load job stalled.
  • hourly also stopped -> the refinery/Airflow pipeline itself is down. AQS will stay 404 until it is restarted and backfilled.

The daily rollup and the AQS load are fed by the same stage, so pageview_complete's last date and AQS's last 200 normally match exactly. That correspondence is what upgrades "probably upstream" to "provably upstream".

Don't expect a status page

wikimediastatus.net covers reader-facing site availability, not the analytics pipeline; an AQS stall will not appear there. Search Phabricator instead: this recurs (e.g. T427171 "PageView tool not updated since 21 May 2026", T330184 "Missing Pageviews Data" where the dumps were missing and the API 404'd for the same day). Grep your own historical logs for the previous occurrence to date the last one.

The trap after upstream recovers

A common design is a nightly cron that launches one poller per language with a bounded poll window:

get_data.py --update --lang en --project wikipedia --poll 36h --poll-interval 15m

with the target date defaulting to date.today() at launch. Consequences:

  • Pollers pile up. One batch per night that never succeeds. 28 languages x 2 nights = 56 stuck processes; at ~23 MB RSS each that is ~1.3 GB, enough to exhaust swap on a 4 GB box. ps -eo pid,lstart,etime,args | grep get_data and group by lstart to count batches.
  • Days silently fall off the end. A batch whose 36h window expires before upstream backfills is gone forever; the code just breaks out of the poll loop. Only the days whose pollers are still alive recover on their own.
  • So after upstream returns, each expired day needs an explicit backfill run, and the backfill window is usually relative to today (for day in range(N, 1, -1) = today-N .. today-2), not an absolute date.

Verify recovery, don't assume

Compare the newest generated day page on disk against the newest 200 from AQS:

find static/en/wikipedia/2026 -name '*.html' -newermt '2026-08-01' \
  -printf '%T@ %p\n' | sort -rn | head -3

If the newest day page equals the last date AQS serves, your pipeline is healthy and merely starved; there is nothing to fix locally.

While you're on the box

An app writing nginx logs to its own directory (/home/<user>/<app>/logs/access.log) is invisible to /etc/logrotate.d/nginx, which globs only /var/log/nginx/*.log. These grow without bound and are a frequent co-discovery when you ssh in to debug something else.

No signals yet