← All workLogistics datapreview2026

BorderFlow: corridor state for Southern Africa

On this page
  1. In short
  2. The question
  3. What it measures, and what it refuses to
  4. Design decisions
  5. What it has found so far
  6. Stack
  7. Links

In short

  • WhatCorridor pressure on the Beitbridge route, where no wait times are published.
  • HowDaily port calls at Durban, Beira and Maputo from IMF PortWatch.
  • ResultA growing open series; the forecast waits for real labels.

The question

Beitbridge is the busiest inland border in Southern Africa and nobody publishes how long it takes to cross. Hauliers and manufacturers moving goods between South Africa and Zimbabwe plan drivers, fuel and perishables around a queue with no public measurement.

The obvious project is a wait-time forecast. I did not build it, and the reason is the centre of this work.

What it measures, and what it refuses to

There is no public ground truth for crossing times. No agency publishes them and no open dataset holds them. A model trained on nothing can only be scored against nothing, and a forecast with no labels is a guess with a chart on top. Anyone who works the corridor knows what the queue did last Tuesday; a chart that does not would lose them on day one.

So version one forecasts nothing and measures what is labelled: seaport throughput at the three ports that feed the corridor, Durban, Beira and Maputo. IMF PortWatch derives daily port calls and cargo volumes from AIS vessel tracking and publishes them openly. A ship that discharges in Durban on Monday becomes trucks on the N1 later in the week, so the series is a real, checkable signal about corridor pressure.

The border layer gets built by collecting labels, not by modelling. A driver or dispatcher records a crossing in about thirty seconds. Only when there are enough labels to hold out a test set does a forecast get built, and it ships with its error rate measured on crossings it never saw.

Design decisions

The collector never mistakes a network failure, or an error dressed as success, for a day with no ships.

Technical detail
  • A network failure is never an absence of shipping. Every run appends a record, with the error text when it fails, and SourceUnreachable is its own exception type so no caller can confuse the two.
  • The endpoint is discovered, not hardcoded. Each run resolves the dataset through the ArcGIS Hub API and logs the URL it used.
  • An error that arrives with HTTP 200 is still an error. ArcGIS answers malformed queries with a success status and an error in the body; reading that as zero rows would record a fault as a day with no ships.
  • Append-only JSONL in git. History is the provenance record, and deduplication by port and day makes reruns idempotent.

What it has found so far

Collection is the product right now. The dataset is worth little on its first day and a great deal after ninety, which is why the schedule runs before the analysis exists.

The chart is drawn from a weekly snapshot of the published series.

Daily port calls at Durban, Beira and MaputoThree aligned panels, one per port, showing daily port calls as thin bars and a 7 day rolling mean as a line, 17 April 2026 to 16 October 2026, 547 observations from IMF PortWatch via BorderFlow.May 2026Jun 2026Jul 2026Aug 2026Sept 2026Oct 2026Durban0107.1Beira02.551.0Maputo053.0

Daily port calls at Durban, Beira and Maputo with a 7 day rolling mean, 17 April 2026 to 16 October 2026, 547 observations; the last 7 day means are Durban 7.1, Beira 1.0, Maputo 3.0.

Daily port calls (bars) and the 7 day rolling mean (line), 17 April 2026 to 16 October 2026, 547 observations. Source: IMF PortWatch, collected by BorderFlow.Chart: drawn from the BorderFlow data snapshot, refreshed weekly.

Stack

Technical detail

Python and httpx, collection twice daily on GitHub Actions, 13 tests with no network, code under Apache 2.0 and data under CC BY 4.0.

Want to talk about this work? Email me or download my CV.