Drayage appointments nobody can keep
Rebuilding a container terminal appointment system as a scheduling problem, using published gate-turn-time data. The published slots were infeasible a third of the time.
01 The problem
Ports and rail ramps allocate 1-hour appointment windows for container drayage trucks. On paper, the capacity matches crane throughput. In reality, drivers arrive to find queues stretching onto access highways, turn-times tripling, and appointments forfeited through zero fault of the carrier.
The system was optimizing for terminal gate smoothing rather than round-trip feasibility for the motor carrier.
02 The data
Public terminal throughput tables and gate logs from West Coast port data feeds.
| SOURCE | RANGE | ROWS |
|---|---|---|
| Gate turn-time logs | 2024-01 – 2026-05 | 124,800 |
| Hourly vessel discharge logs | 2024-01 – 2026-05 | 21,200 |
| Chassis inspection records | 2025-01 – 2026-04 | 14,500 |
03 What I built
A bipartite matching algorithm that couples terminal appointment slot availability with motor carrier round-trip feasibility windows. Instead of a static first-come-first-served gate reservation, appointments are offered as dynamic bundles that guarantee return-bobtail viability.
04 Result
| SCHEDULER | MEAN TURN TIME | INFEASIBLE SLOTS | COMPLIANCE |
|---|---|---|---|
| Static FIFO Portal | 84 min | 34.2% | 61% |
| Round-Trip Feasible Matching | 51 min | 3.1% | 94% |
05 Where it broke
- Unannounced chassis flips. Drivers reserved dry vans but were reassigned reefer chassis on site, violating the axle load assumptions.
- Crane downtime cascades. A 20-minute crane outage caused upstream appointment invalidations that the solver had to recompute in real-time under high Redis lock contention.
06 Run it yourself
$ git clone https://github.com/gospinup/spin-03-drayage
$ cd spin-03-drayage && pip install -r requirements.txt
$ python run_benchmark.py
07 Discuss
Every spin has a thread on GitHub Discussions. If a constraint looks over-fit, if the baseline is too easy, or if you’ve solved this properly in production and I’m busy reinventing it badly — say so there. Corrections get credited in the spin itself.