Guides › Cargo routes

Cargo Routes - Complete User Guide

Cargo Routes turns the raw AIS voyage history of the whole tracked dry-bulk fleet into a ranked map of real trade flows. It answers the broker/charterer/owner question "where is cargo actually moving, on what ships, how fast, and at what implied cost?" by aggregating every laden port-to-port leg into origin→destination lanes and scoring each lane on volume, tonne-miles, transit, turnaround, fleet composition and week-over-week momentum.

What the page measures, and the macro-collapse trick behind it

Each row is a cargo route (trade lane): a single laden journey from one cargo event (load port) to the next cargo event (discharge port). The intro banner at the top states the rule, and the backend (cargo_routes() + _macro_legs_for_ship()) enforces it precisely:

Why it matters: because the noise is stripped out, what remains is a clean read of genuine load→discharge demand - real trade direction and intensity, not raw port-call churn.

Two views by role. The full live board (every lane, the multi-port voyages tab, Route-Index enrichment) is an internal/admin tool. Members see a focused filtered view: choose a region, a tonnage band and (optionally) a date range, and the page returns just the matching load→discharge lanes - a slice for your criteria, not the whole fleet. Same engine and definitions; only the scope differs. Every row carries a Details link that steps into that lane’s own history page - freight index, the ships that ran it, and its seasonal rhythm - the same per-lane drill-in the full board offers.

Call classification is one rule across both feeds. The draught change at a call, converted to tonnes with the ship’s TPC, must be large enough relative to her size to count as a cargo operation (a smaller change reads as a bunker call); tiny draught blips in broker-reported stays are treated as noise. Historic legs were re-derived under the same rule, so route tonnages are consistent over the whole archive.

Coverage rule (2026-07). Routes are derived from live AIS inside its own tracking eras and from broker-reported port calls outside them (pre-tracking, reception holes, post-AIS). Broker calls only become route endpoints when the ship physically reached the port (moored/anchored evidence) - a declared ETA never mints a route on its own.

Discharge ports are never booked as origins (2026-07). If a ship arrives somewhere laden, discharges, and sails onward empty before reloading, that first port is a discharge, not a load - the route is attributed to where she actually reloaded, never to the discharge port. A leg that leaves a port in ballast (light draught) after arriving laden is treated as a repositioning leg, so no phantom “discharge-port → next-port” cargo lane is created.

The filter bar - narrowing the universe of voyages (server-side)

The grey strip under the intro is the fetch filter bar. Changing any of these and clicking Apply re-queries /api/cargo_routes and rebuilds the whole page:

How to use it: set hard scope (date / DWT / segment) with the fetch filters, then use the instant search to pinpoint a port or country without a reload. Note: the page deliberately requests the full set (limit=20000, the server's hard ceiling), so nothing below that ceiling is silently truncated.

The member view - load region + tonnage, optional discharge region, and searching results

Members without the full admin board land on a simpler, restricted Cargo Routes view at the same /cargo-routes URL: pick a Region and a Tonnage band (both required; a discharge region and a date range are optional) and press Show routes to see the matching lanes for that slice of the fleet.

The Region filter matches the load (departure) side only. Selecting e.g. Black Sea shows lanes that loaded cargo in the Black Sea - wherever they discharge - not lanes that merely discharge there after loading somewhere else entirely. This is a deliberate, one-sided match: pick the region you load from, and the destination column is free to show anywhere in the world the cargo actually went.

Optionally narrowing the discharge (destination) side. Alongside the load region you can now also pick a discharge region, or leave it on Any discharge region. Leave it on Any to see everywhere your chosen load region ships to; pick a discharge region to see only the lanes that both load in your chosen region and discharge in that one. The discharge choice is always optional - the load region and tonnage band stay the only required filters, so you can still ask for a load region on its own and get the full picture.

Searching the results (the 🔍 box under the filter bar). Once routes are shown, this box filters the already-loaded rows instantly - no reload - by load or discharge port name/region, the same in-memory pattern the admin board's table search uses. Clear it to see the full filtered set again.

The Window chips - picking your lookback

Below the filter bar is the Window pill row, setting the default scan window when no explicit From/To date is entered: 30d, 90d, 6mo (180d), 12mo (365d, the default, lit in accent), 24mo (730d), and All (3650d).

What to look for: short windows (30/90d) show what is hot right now; long windows (12/24mo, All) reveal the structural trade backbone. A lane that ranks high on 30d but not 12mo is a fresh surge; one that's top on both is a durable artery. Tip: the metrics use the departure date, so very recent days are right-censored - a leg only exists once the ship is seen arriving.

The seven KPI hero cards

The accent-coloured tiles (a 4-across grid, wrapping to a second row) summarise the filtered dataset at a glance. Read them as two groups - the first three cover every ranked lane, the tonne-mile/CO₂ pair cover only the top lanes:

Why it matters: the heroes are your sanity check. If "Total voyages" collapses when you tighten a filter, you've over-narrowed. If freshness goes red, treat the most recent lanes cautiously.

The three Top-20 lane bar charts

Beneath the heroes sit three horizontal-bar leaderboards. Each row shows: a lane label (clickable origin and destination port names, each linking to /port/<code>), a small arrow between them that links to that lane's dedicated history page (/lane?from=…&to=…), an optional segment pill (the lane's top ship segment), a proportional accent-filled bar, and a right-aligned value. Each bar's width is relative to the largest value in that chart, so you read relative throughput instantly. Each list shows up to 20 lanes; an empty filter shows "No data for the selected filter."

How to read them together: a lane high on voyages but low on tonne-miles is short-haul/high-frequency (regional grain or coastal coal); a lane high on tonne-miles but mid-pack on voyages is long-haul ballast-burning demand (the ton-mile-heavy trades that tighten the global market). Comparing the three rankings tells you whether activity on a corridor is about frequency, ship size, or distance.

The All-routes table - the fifteen columns

The full lane table sits at the bottom. Every header is clickable to sort; the sorted column turns accent-coloured. Columns:

Sorting behaviour: clicking a header sorts by that field; clicking it again reverses direction. Text columns (origin/destination/segment) start ascending, numeric columns start descending, and any sort change resets to page 1.

Search, pagination and lane drill-down

Above the table is a second toolbar:

Lane drill-down. Both the bar charts and the table link out two ways: a port name opens that port's page (/port/<code>); the / arrow opens the dedicated lane history page (/lane?from=ORIGIN&to=DEST) for the time-series of that specific corridor. Use the lane page to confirm whether a top-table lane is a steady artery or a one-off spike before you act on it.

A note on completeness vs cost: the cheap metrics (voyages, DWT, transit, ships, operators) are computed for every lane; the expensive ones (precise sea-route distance, implied hire, CO₂) are bounded to the top lanes by voyage count. So a deep-tail lane may show "-" for Implied $/d or CO₂ even though its voyage and tonnage figures are complete - that's by design, not missing data.

Confidence dots. Lane/voyage numbers now carry a small confidence dot - strong (many real voyages), moderate, or thin/modeled - so you can see at a glance how firm each figure is. Thin lanes are indicative and firm up as voyage coverage grows.

The lane page now maps the actual route. For a port-to-port lane it draws a map with the genuine paths recent ships sailed (reconstructed from their own position fixes, so they hug the water and never cross land), over a dashed sea-route reference line, with load/discharge markers. It also shows the total distance (real sea route, great-circle fallback) and a Transit time by vessel class table - how many days each tonnage band actually takes on this lane and the implied average speed. Actual tracks only exist for voyages still inside the position-retention window; older ones fall back to the sea-route line, and the set deepens as history accrues. The page also shows a Currently sailing this lane layer - ships in transit right now (laden, en route to the discharge port per their broadcast destination), drawn in amber with a live position, path-so-far and dashed projection. This is a leading signal that turns into a completed voyage on arrival; it is kept separate from the historical counts, never blended.

The Season column

Each lane row now carries a tiny 12-bar Season strip - departures by month of year, January to December, with the busiest month at full height (hover for exact counts). It answers at a glance whether a trade is steady year-round or pulses with a crop / weather season, and it keeps deepening as more voyages accrue: the underlying monthly lane statistics are stored permanently, so the strip converges on the lane’s true multi-year rhythm rather than a single season’s noise.

Multi-discharge voyages

When a ship carries one cargo and part-discharges it at several ports down a coast, that is one voyage - not separate port-to-port lanes. The page reconstructs these from the ship's full leg chain and shows them as a single load → discharge ports entry, with the number of voyages, distinct ships and the operators that ran each one.

A second or third ‘load’ on a voyage is almost always a nearby port or an anchorage-region name (for example a mid-ocean anchorage code), not a genuine second loading - so we fold it into the first load and the voyage appears as a normal first-load→discharge lane in the routes table above, rather than a phantom multi-load. There is no per-port tonnage split - the AIS/draught feed isn't reliable enough to say how much was lifted at each call, so we show which ports, not how much.

How load ports are resolved - anchorages fold to the real berth

A bulker often loads while sitting at an anchorage (a staging area offshore), and the AIS geofence records that anchorage, not the commercial berth it serves. Left raw, a cargo would look like it loaded at “Campha Anchorage” instead of Campha. We fix this at the source: when a voyage loads at an anchorage, the cargo’s recorded load port (its origin) is lifted to the real berth the anchorage serves - matched first by the anchorage’s own name (“Campha, VN Anchorage” → Campha) and, failing that, by snapping to the nearest commercial berth a short distance offshore. The ship’s physical departure point is still kept truthfully (it really did sail from the anchorage), but every route, lane and origin you see attributes the cargo to the berth - so the All-routes table reads “Campha → ...”, not the anchorage. A small number of genuinely offshore load points (transshipment anchorages with no berth nearby, e.g. some Indonesian bauxite or Thai gypsum anchorage loadings) are left as-is, because there the anchorage is the real load point. The real city of Anchorage, Alaska is never touched.

The Route Index (RAI) - a route’s world-trade activity by tonnage

Every lane in the All-routes table now carries a Route Index (RAI) - the route analog of the Port Activity Index, and the same figure headlines each lane’s own page (open any route from the table or globe). It scores, on a 0-100 scale, how important and efficient a trade lane is in global dry-bulk trade for its tonnage class. 50 = a typical lane for that band; higher = busier and leaner, lower = quieter. The small pill beside the number is the DWT band the lane is scored in, and the confidence dot shows how much voyage evidence sits behind it (thin / moderate / deep).

It blends three things, each measured against the same-band universe of lanes (so a Capesize iron-ore run is never judged against a Handysize coastal hop):

The published 0-100 number is a within-band percentile - a lane in the 90th percentile of its band sits in the top 10% most active routes of that size. A separate raw index, scaled so a band-typical lane reads as the neutral baseline, is stored underneath so the value can be tracked as an absolute series over time. RAI is a pure read of observed voyages - it does not use freight price (the Index $/d column beside it is the separate $/day anchor), so it stays a clean measure of activity, not a restatement of rate. It is computed over the same window as the board and saved to an append-only daily history, so - like the freight index - it deepens into a genuine record of how each corridor’s standing in world trade shifts over time.

More guides