Trimtabist

The US Trade Ledger — every US container gateway, every partner country, every month. Census-recorded, AIS-verified.

← all methods · TT-009 instrument page · raw markdown: ?raw=1

TT-001 · Berth queueing — method

Grade: OBSERVED. Position, speed over ground, and our own receive clock, from our

own receivers. Nothing modelled, nothing crew-entered.

Status: NOT PUBLISHABLE. Two independent defects push the number toward zero

exactly when congestion is worst. Both are documented below. This file describes a

working instrument that is deliberately not yet reporting.


What it measures

Average Waiting Rate, the UNCTAD/World Bank congestion indicator:

epsilon  =  SUM(hours waiting for berth)  /  SUM(hours alongside berth)

Kek Choo Chung, Port Performance Indicators, World Bank, Transport No. PS-6,

December 1993, indicator 6 (5a/3), codifying UNCTAD's *Manual on a Uniform

System of Port Statistics and Performance Indicators* (1983). In queueing papers the

same quantity is ε = Tw/Ts.

Two things about the definition that are easy to get wrong, and we got both wrong first:

first computed a median of per-call ratios. It read 0.00 at every gateway and

discriminated nothing, and short berth stops made individual denominators tiny so

ratios exploded — STAR SIRIUS led the table at 32.97 on 1.9 hours of "work". A

3-hour service floor appeared necessary to suppress that. **Under the aggregate

the floor is unnecessary**: a short berth simply contributes little to the

denominator. The floor was a symptom of the wrong estimator, and removing it

recovered 35 calls (124 → 159).

Benchmarks

accepted design range0.05 – 0.20
PIANC guidance~0.165
UNCTAD overutilisation flagberth occupancy > 70%

**A bare ε has no fixed meaning without berth count and occupancy, and we can observe

neither.** So ε is published as a comparison across gateways and against the design

range — never as an absolute verdict on a port.


How anchoring is detected — physics, not declarations

AIS has a field that says "at anchor" (NavigationalStatus = 1). **We do not use

it.** It is crew-set, and the archive shows why: 3,273 BERTH_START events against

153 ANCHOR_START, because crews set moored far more reliably than anchored.

Instead: a ship at anchor swings around its anchor as wind and tide turn it,

tracing an arc a few hundred metres across. **A ship at a berth is held against a

quay by mooring lines and cannot move.** So the spread of positions while stationary

separates the two — and position is GPS off the transponder, which no human types.

Verified 2026-07-30 on 212 stationary runs. The two mechanisms agree independently,

which is this observatory's whole method:

tight  (spread <60 m, arc <25 deg)  123 stops  median  25 m,   2 deg
       -> 85% had the crew declaring MOORED, 0% at anchor
swing  (spread >=60 m, arc >=25 deg)  31 stops  median 290 m, 168 deg
       -> 74% had the crew declaring AT ANCHOR

Thresholds, taken from the distributions rather than chosen

crew said MOORED     n=173   p10   5 m   p50  24 m   p90  68 m
crew said AT ANCHOR  n= 29   p10  39 m   p50 243 m   p90 376 m

The distributions overlap between 39 and 68 m. A single cut would force a false

binary, so ambiguous stops are labelled and excluded, and the count is published

so a reader can see how much is being set aside.

Rules enforced in code

fix shredded calls: a moored ship's speed reads 0.1, then 1.2, then 0.0 from noise,

and ZIM MOUNT BLANC's single Savannah call came out as six fragments of 0.6–1.5h.

The tell was that berth duration did not scale with ship size — 320–400 m hulls

showed a median 5.0h against 7.7h for 150–250 m hulls, which is backwards.

Fragmentation also converted anchor time into berth time, because a short

fragment of a swinging ship measures tight. Anchor stops rose 41 → 59 once fixed.

closes the run because we cannot claim the vessel stayed put — it does not assert

that it left.

Ships also anchor for bunkers, stores, crew changes, repairs, weather and awaiting

orders, and none of that is queueing. Measured 2026-07-30: of 1,241 observed anchor

hours, only 92 h (7%) are verified as queueing — the other 1,149 h had no

subsequent berth at that gateway. Both figures are reported; only the verified hours

enter the rate.

stop, so an anchor from one visit could be counted as queueing for a berth taken days

later on another. Stops are split into visits, and the boundary is not elapsed

time — observed anchor-to-berth transitions ran from 1.2 h to 37.8 h, so any time

threshold would discard real waiting. The physical test is whether the ship left:

seen beyond 40 nm from the berth centre between two stops, those stops belong to

different visits.

tugs made "berthings per day" read 745 against an honest 35.


Why this is not publishable yet

1. The geofence cannot see an offshore queue

Our bounding boxes reach 5 to 17 nautical miles from centre — Oakland 5 nm,

LA/Long Beach 8 nm, Houston 17 nm.

**In November 2021 LA/Long Beach required waiting ships to hold 150 nautical miles

offshore.** UMAS notes that a 25 nm AIS radius would have reported approximately zero

congestion at the peak of the worst US port crisis on record. For scale: LA's average

wait reached 8.7 days in September 2021, with 86 ships anchored or loitering on

16 November 2021.

So if that event recurred, this metric would not merely miss it — it would fall,

because ships pushed offshore leave the box entirely and never register as anchored.

2. Right-censoring deletes the longest waits

Of 195 reconstructed calls, **35 anchored but had not berthed when the window closed,

holding 800 of 1,202 observed anchor hours — two thirds of all waiting.** Requiring a

completed call preferentially discards the most congested ships.

**The bias grows exactly when congestion is worst. In a crisis this metric sags

rather than spikes.** That is the worst possible property for a congestion index, and

on its own is sufficient reason for suspension.

Fixes, in order of preference: enough calendar time that the archive is long relative

to typical waits; or an estimator built for censoring (Kaplan–Meier) rather than

dropping incomplete cases.

3. Virtual arrival is invisible

Where arrival protocols are modern, a ship slow-steams and berths on arrival — **real

delay, zero anchor time.** ε then partly measures how modern a port's arrival protocol

is rather than how congested it is. Not fixable by widening boxes; only by measuring

speed reduction on the final approach leg.

4. The Ready Reserve Fleet is in the denominator

Found 2026-07-30 by building the live board. CAPE DUCATO, CAPE ARUNDEL, `CAPE

SABLE, CAPE STARR` and USNS hulls are US Maritime Administration Ready Reserve

Force vessels. They are AIS type 70–79 and over 150 m, so they pass the merchant

filter, and they sit alongside for months without working cargo.

They hold 345 of 3,515 berth hours — 9.8% of the denominator. Since ε is

wait ÷ berth, padding the denominator deflates ε by roughly a tenth, and more at

Norfolk where three of seventeen berthed hulls are Cape-class. Same class of defect as

the tugboats: a filter that admits the wrong fleet.

Fix: exclude by hull identity, not by name pattern alone — CAPE would also match

legitimate commercial vessels. The vessel registry's operator field already names

the US Navy and MARAD on some of these.

5. Berth durations are clipped by the observation window

Every long stop reads 63–66 hours, which is the archive length, not a call length. A

genuine container call runs 12–48 hours. So these are floors, not measurements

"at berth for at least 66 hours" — and they inflate S, which again deflates ε.

Three independent mechanisms now push ε toward zero: right-censoring deletes the

longest waits, window-clipping inflates berth time, and laid-up reserve hulls pad the

denominator. All three flatter the ports. That consistency is the strongest argument

for keeping the series suspended until the archive is long enough for the first two to

become second-order.

6. Liner schedules contain deliberate buffer

Waiting inside the buffer costs almost nothing; only waiting that breaks the schedule

costs money. AIS cannot distinguish them. Stated as a permanent limit.


Reporting

Report the triplet, because no single figure is sufficient:

incidenceshare of calls that waited at all — a long-standing port KPI ("berth-on-arrival %"), and directly testable against Erlang C
epsilonthe aggregate waiting rate — the UNCTAD/World Bank indicator
p90the tail, in hours not ratio — the bad experience

The median is deliberately absent and the page must say so: it is 0 by

construction in a low-congestion regime and carries no information.

Print the call count beside every figure. About 15 calls per gateway is too thin

for a stable p90; pool to port-quarter or report incidence and ε only.

Never publish a composite rank. The World Bank's own rank aggregation placed

Beirut 11th on one method and 63rd on the other — same port, same data.

Never publish ε as a bare league table. LA/Long Beach moved record volumes in

2021; the queue was demand exceeding capacity, not port failure, and attributing loss

to the port is a category error. Publish volume beside ε so slow-because-busy is

visibly distinguishable from slow-because-inefficient.


Scope limit to state proactively

This measures waterside berth queueing only. We cannot see crane moves, gate

transactions, yard density or labour. Bichou's standing critique of the World Bank

CPPI — that examining berth performance alone biases toward shipping-line interests

and ignores landside congestion — applies to this instrument too. Say it in the

method rather than waiting to be told.


Baseline for "excess", not gross

UMAS/UCL (December 2024, AIS-derived) find ships spend **4–6% of operational time —

15–22 days a year — waiting at anchor before berthing, as the 2018–2022 norm.**

Container ships sit below that average, and waiting falls with ship size.

So the honest framing is excess above a published baseline, not gross waiting.

Consequence that needs testing: if waiting falls with ship size while service time

rises with it, ε falls doubly with size — so ε could differ between gateways because

of fleet mix rather than performance. calls.gross_tonnage is stored for exactly

this test. It is not yet runnable: only 3 gateways show any waiting at all.


Data model

stops       one stationary period: kind, minutes, spread_m, heading_arc_deg, fixes
calls       one port call: wait_minutes, service_minutes, ws_ratio, excluded_because
build_runs  every rebuild, with the thresholds in force

Derived from the raw archive (ais_position), not by hooking the live detector.

The recorder archives; the analyser derives. A threshold change is therefore a re-run,

not a migration, and nothing is lost to a bug in a state machine. Idempotent: the same

archive produces the same rows.

node calls.js build     rebuild stops and calls from the archive, then report
node calls.js report    report without rebuilding

Checks to register before anything publishes

checkquestion
coverageour monthly call count at LA against POLA's published vessel calls — the one gateway with a public denominator
fleet mixdoes ε correlate with mean vessel size across gateways? If so it is measuring fleet composition
incidence vs theorymeasured incidence against Erlang C at plausible occupancy. Ours implies 23–44% occupancy; US gateways run 50–70%. Part is genuine (berth windows make arrivals scheduled, not Poisson), part is the geofence gap
censoringmedian wait of gap-closed against movement-closed calls

Threshold sensitivity — RUN 2026-07-30, passed

The 40 m / 120 m spread cut is our judgment, so it was tested across seven plausible

alternatives (berth-max 30–68 m against anchor-min 80–150 m) by reclassifying from the

persisted spread_m and recomputing ε:

gatewayε across all seven settings
savannah0.059 – 0.062
la_longbeach0.028 – 0.034
oakland0.000 – 0.038 — unstable
all others0.000 throughout

The threshold choice is not load-bearing where the sample is adequate. Oakland

flips only because its whole figure rests on a single call whose swing fell between

120 and 150 m — a sample-size problem, not a threshold one. **Oakland's ε must not be

quoted.** Incidence is more sensitive (1.3%–3.9%) but stays in the same very-low

regime throughout.

The service-floor sensitivity check (1h/3h/6h) became unnecessary when ε moved to the

aggregate: the floor was removed entirely, so there is no longer a floor to vary.