A live maritime intelligence platform tracking sanctioned and dark-fleet vessels globally, built from public data and running continuously since May 2026.
Dark Fleet Watch is one of our own systems — built to answer a specific question that our clients in maritime insurance and compliance keep running into. When a vessel is renamed, reflagged and re-registered through opaque ownership chains, how do you know it’s the same hull that appeared on last year’s sanctions list?
The platform ingests global vessel-tracking signals in real time — roughly 130,000 to 220,000 position reports per hour — and cross-references them against sanctions lists published by the US Treasury, the UK Foreign Office, and Ukrainian defence intelligence. On top of that sits a behavioural layer that watches for the things a static list cannot see: AIS blackouts, implausible positions, proximity to known transshipment activity.
At any given moment the platform is monitoring around 2,300 vessels under active designation, drawn from more than 3,600 individual sanctions entries across multiple lists. A vessel that appears on three different lists is one vessel with three pieces of corroborating evidence — the sort of distinction that matters when a claim is later examined.
For any flagged vessel, the platform produces a dated evidence record: what was knowable, and when. That is the artefact a compliance officer needs when a regulator asks the same question later.
A single 4 GB virtual server. PostgreSQL with the TimescaleDB extension handles the time-series data — currently around 100 million position records across a rolling thirty-day window, automatically pruned. FastAPI serves the web interface; PM2 supervises the ingestion, detection and refresh services independently, so a failure in one does not cascade to the others. The whole thing runs for less than £75 per year in infrastructure.
The database work here is where the interesting engineering lives. A single query rewrite reduced the front-page load time from 45 seconds to 0.3 seconds — a factor of 130 — by teaching Postgres to seek per vessel rather than scan across all of them. Retention policies keep the working set stable indefinitely without operator intervention. Ingestion has survived — and correctly diagnosed — a two-week upstream data outage without corrupting the historical record.
Because it demonstrates the shape of database work we do for clients: taking a messy, heterogeneous world of public data (sanctions lists in three different XML dialects, a Cloudflare-protected Ukrainian government catalogue, a real-time WebSocket feed) and turning it into something quiet, reliable, and answer-shaped.
The same pattern — ingest, structure, monitor, alert — sits under most of the intelligence work After the Rain builds for its clients.