Skip to content
Straits

Methodology

How the data gets here.

Each indicator on the page, with the upstream feed where we can name it, how fresh it is, and what it can’t tell you. Each live section also surfaces a per-indicator data-health chip that flags live, curated, or stale at a glance. A separate Supplementary feeds section at the bottom covers indicators derived from third-party aggregators whose upstream we keep private to preserve access. Read this before quoting any number.

Hormuz Index · v0.6.0

How the Hormuz Index is computed.

Why two numbers. v0.1 of the index combined current-state signals (insurance, transits, options vol, recent events) with a single forward-looking signal (Polymarket) into one 0–100 headline. A reader pointed out the obvious: four of five inputs measure what just happened, so the headline was effectively a state reading dressed as a forecast. v0.2 splits the brand into two parallel indices, each backed only by inputs that match its claim. Both ship in lockstep, recompute every 5 minutes, share the same bands and rails, and publish per-input contribution on the audit endpoint.

Crisis Pressure Index: state.

What is happening right now. Four measured signals about the physical strait and the markets that price its present condition. The override rule fires here: when any single input scores at or above 75, the headline is floored at 0.9× that input’s score, so a high-severity signal cannot be averaged away; the physical-strait override is load-bearing for crisis severity.

What this does not measure. The Crisis Pressure Index is not a forecast. A high value tells you the present is bad; it does not tell you whether things are likely to get worse. The Escalation Forecast below is the forward-looking read.

  1. 30%

    Physical reality

    IMF PortWatch daily transit count as a percentage of the pre-crisis baseline, so a raw of 11 means transits are running at 11% of normal, not 11% below it. The unique physical-strait signal: cannot be faked by markets, independent of sentiment.

    IMF PortWatch chokepoint6

  2. 25%

    Insurance

    War-risk insurance multiple vs peace-baseline rates for VLCC voyages through Hormuz. The slowest input to react but the most consequential when it moves: uneconomic at standard rates above 4×.

    Trade press + proprietary aggregation

  3. 25%

    Event pressure

    Severity-weighted count of escalation events, with exponential decay on a 72-hour half-life. Weights are assigned by event type and severity (closure and major strike heaviest, negotiation negative), not by an external conflict scale. Most of the weight sits inside the last 24 hours, but the window is the full 72: measured 2026-08-08, the feed held 32 events inside the decay window and 27 inside 24 hours, so a handful genuinely contribute from the 24 to 72 hour tail.

    warEvents: GDELT 2.0 plus maritime and news RSS feeds and curated timeline entries

  4. 20%

    Oil-market dread

    CBOE Crude Oil Volatility Index (OVX): 30-day implied volatility on options over USO, the United States Oil Fund, which tracks near-month WTI. Not a Brent instrument. Treated as a state signal: spot vol is overwhelmingly reactive, measuring repricing that has already happened.

    CBOE OVX, direct

Escalation Forecast: forward-looking signal.

Renamed from Escalation Probability in v0.3.3. The composite blends prediction-market odds with a Brent–WTI price spread and play-money Manifold contracts, so the single number is a directional forecast signal, not a calibrated probability you could bet against at those exact odds. The math is unchanged.

What markets and forward-dated contracts price for a bad outcome. The forecast target is the union: closure or partial closure of Hormuz, a major strike on Gulf infrastructure, a US military casualty, Iranian retaliation, or Brent above $150. Polymarket, Kalshi, and Manifold contracts are mapped to this union; dollar-weighted aggregation pools them by their lifetime traded volume (Manifold mana converted at 100:1 USD-equivalent). Because the weight is lifetime, not recent, an old listing with a large trading history outweighs a newer one even if the newer contract is moving more money right now. Each matched contract is classified by orientation before aggregation: contracts that frame YES as the bad outcome (closure, strike, retaliation, invasion) contribute their YES probability directly; contracts that frame YES as de-escalation (peace deal, ceasefire, traffic returns to normal, blockade lifted) contribute 1 minus their YES probability, so the aggregate consistently reads as "markets-implied probability of the bad outcome."

Horizon mix, not a 30-day window. Matched contracts are not filtered to any fixed resolution date; they span horizons from single-month contracts (a PortWatch traffic-normal date, a near-term ceasefire) out to multi-year ones (invasion or regime-change contracts dated through 2027), and pooling is by dollar volume, not time to resolution. A distant, heavily traded contract can dominate the composite even when the near-term contracts move less money. Read the number as a forward-looking escalation signal shaped by whichever matched contracts currently carry the most volume, not as a probability keyed to any single horizon such as 30 days.

What this does not measure. The Escalation Forecast is not a state reading. Forward contracts price what speculators are willing to wager on, not whether ships are moving today; the Crisis Pressure Index above answers that. No override rule fires here: a forecast should be a smooth probabilistic number, not a threshold flipper.

A contract out of clock carries less weight. Every contract has a close date, and as that date arrives it stops pricing the strait and starts pricing the calendar. The effect is worst on the de-escalation framings this index inverts. “Strait of Hormuz traffic returns to normal by July 31?” trading at a fifth of a cent two days out is not a market saying escalation is likely; it is a market saying time has run out. Inverted, it enters the aggregate at near-certainty. Because pooling is by lifetime volume and the heaviest contracts are the oldest, this bias ran one way every cycle: on 2026-07-29 that single contract held 27.6% of the matched Polymarket pool and put 14.7 points into a published 60. Since v0.6.0 each contract’s volume weight tapers linearly to zero across its final 14 days.

Which is also why rollover no longer steps the number. Venues are queried for open contracts only, so a contract leaves the aggregate the moment it resolves. Before the taper that departure moved the published value on its own, with nothing having changed in the strait. Now a contract is down to nothing by the time it goes, so there is no step to explain away. Contracts currently inside the taper window are published with the weight each has left, under nearExpiryContracts on /api/index, and the full contract list is on /api/v1/markets.

Liquidity floor. When combined Polymarket + Kalshi + Manifold lifetime traded dollar volume across matching contracts falls below $15,000, the Escalation Forecast reports as low-confidence and the hero shows it in a muted treatment. Combined lifetime volume across the three venues runs in the hundreds of millions of dollars, so this floor rarely fires. Manifold carries its own, separate minimum traded-volume floor; when Manifold volume falls under it, Manifold is dropped from the aggregate and its weight redistributed to the other venues, which is the check doing the actual work day to day. The combined floor above does not collapse a weight or hide the number; the right behavior under thin liquidity is honest uncertainty, not silent reweighting.

Why Kalshi left and came back. v0.3.2 dropped Kalshi from the composite after a 2026-05-27 audit walked all 20,000 currently-open Kalshi markets and found zero actively-traded Iran/Hormuz forecast contracts; its 0.15 weight was redistributed pro-rata. A 2026-06-10 re-audit found Kalshi had since listed heavily traded Hormuz series (led by KXHORMUZNORM, which resolves on the IMF PortWatch 7-day moving average of transit calls going above 60; the dominant Polymarket contracts read the same series but resolve at or above 60, so the two differ at exactly 60.0), and v0.4.0 restored Kalshi at its original 0.15 weight the same day. Both audits are documented in the changelog.

  1. 40%

    Polymarket forward

    Dollar-weighted mean implied probability across matching Polymarket contracts on Hormuz closure, Iran escalation (US strike or invasion), US-Iran conflict, and oil-shock outcomes. Reopening/normalization-framed contracts are orientation-inverted. Contracts asking whether a named bilateral agreement gets signed by a set date are excluded: inverted, they price how long diplomacy takes rather than anything about the strait, and one such contract was entering at 0.98 and holding 14% of the component. Contract close dates span from weeks to the 2027 horizon; the aggregate is the blended market-implied read, not a single fixed-window probability. Volume weight tapers linearly to zero over a contract's final 14 days, so a contract that has run out of clock cannot steer the reading; totalVolumeUsd on /api/index is therefore tapered volume, not the venue's reported figure.

    Polymarket Gamma API

  2. 20%

    Brent–WTI spread

    Brent price minus WTI price, in USD, on a shared delivery month. WTI prices US/Cushing crude; Brent prices waterborne Mideast/North-Sea crude that has to transit the Strait of Hormuz or pay the Cape reroute. A widening Brent premium means real money is pricing Brent-specific access risk separately from US supply, a Hormuz signal by construction. Normal range $2–4; sustained Mideast crises push it to $5–10+. The only Escalation input not sourced from a prediction-market venue: a deep, liquid, independent forecast signal. Note the two contracts do not roll together: Brent rolls about three weeks ahead of WTI, so for most of each month the front-month pair straddles two delivery months and differencing it would price the calendar rather than the crude. Both legs are therefore taken on the later shared month, which is the front month for only about one week in four.

    Brent − WTI futures spread on a shared delivery month · intraday futures feed

  3. 25%

    Manifold forward

    Mana-weighted mean implied probability across matching Manifold contracts on Hormuz and Iran conflict outcomes. Play-money market; mana converted to USD-equivalent at 100:1 for liquidity-floor accounting. Matching requires both a theatre term (the strait, the Gulf, or Iran) and a conflict-event term, so the venue's broad Iran-politics shelf (regime-change and leadership contracts, which are not in the forecast target) no longer enters the aggregate. Because Manifold is play money and its genuine Hormuz shelf is often only a few hundred dollars deep, the component carries its nominal weight only when matched volume clears a $5,000 floor; below that it is marked stale and its weight is redistributed across the other forecast components, which is disclosed in the degradedComponents field on /api/index. That floor measures tapered volume, since weight tapers linearly to zero over a contract's final 14 days: a shelf made of contracts about to close is not a shelf.

    Manifold Markets public API

  4. 15%

    Kalshi forward

    Volume-weighted mean implied probability across matching Kalshi contracts, dominated by the KXHORMUZNORM series, which resolves when the IMF PortWatch 7-day moving average of transit calls goes above 60. Polymarket's reopening contracts read the same series but resolve at or above 60, so the two differ at exactly 60.0. A regulated US exchange; Kalshi reports volume as a contract count and publishes no dollar figure, so the weight is a share count, which is comparable within the venue but not against Polymarket's traded dollars. Reopening-framed contracts are orientation-inverted so likely reopening reads as low escalation probability. Because the series is a ladder of the same question at different dates, the near rungs price the calendar and the far rungs price the war, so volume weight tapers linearly to zero over each contract's final 14 days.

    Kalshi trade API v2

Why a non-market forward input. Until v0.3 the Escalation Forecast pulled exclusively from prediction-market venues. Three venues, broadly the same participants; a fair critic could call the composite “a poll of prediction markets, not a forecast.” The Brent–WTI front-month spread answers that. When real money widens Brent’s premium over WTI, it is pricing Brent-specific access risk (Hormuz transit, Mideast supply) separately from US/Cushing crude. The spread is quoted continuously by two of the deepest commodity futures markets and is uncorrelated with the prediction-market crowd. It will not move the index in calm regimes (the $2–$4 baseline scores low by design), but during a developing crisis it gives the forecast a deep, liquid second opinion. No paywalled feeds inform either index.

Spread calibration · linear interpolation between anchors

$0 premium
score 0
$2 premium
score 15
$4 premium
score 35
$7 premium
score 70
$10 premium
score 90
$15+ premium
score 100

Negative spreads (WTI priced over Brent) reflect US Cushing logistics, not Hormuz, and clamp to 0.

Decay and rails, applied to both indices.

Inputs are not smoothed before they enter the composite: each adapter’s reading goes in as it stands, so a jump in one input reaches the raw composite the same tick. Smoothing happens at the index level only. Each index decays asymmetrically against its own previous value: rises propagate instantly, falls smooth with a 36-hour half-life. This mirrors implied-volatility behavior: tension builds fast and resolves slowly.

Event pressure from GDELT decays exponentially with a 72-hour half-life. The feed is the shorter constraint: it carries roughly the last 24 hours, and measured on 2026-07-31 no retained event was older than 36 hours, so an event stops contributing well before the decay curve alone would suggest.

Hard 24-hour rails clamp each index: neither can rise more than 25 points or fall more than 10 points in a 24-hour window. The floor is fixed; we will not signal an all-clear faster than the underlying inputs warrant.

One consequence worth stating plainly: because of this smoothing, the published reading is deliberately not the bare weighted sum of the inputs you see in the component table. On a fast move the two diverge. If the components weighted-average to 27 but yesterday’s reading was 78, the 10-point fall rail and 36-hour half-life mean today prints near 68 and converges toward 27 over several days, not in one tick. That is the intended anti-whipsaw behavior, not an error. To keep it honest rather than hidden, the hero labels the trajectory (“cooling toward 27”) whenever the gap exceeds 5 points, and the /api/index response carries a reconciliation block exposing the raw composite, the decayed value, and the rail-limited published value side by side. Sum the components yourself and you land on rawComposite; the smoothing chain from there to the headline is fully shown.

Missing inputs, applied to both indices.

When an input is unavailable or stale (its upstream feed is down, returns no reading, or carries only a frozen last-good value past its refresh cadence), its weight is redistributed pro-rata across the inputs that remain. The published composite then sums over current data rather than treating a dark feed as a zero score or carrying a stale reading at full weight. This is honest degradation, but it does mean the operative weights shift away from the headline figures while a feed is out. If CBOE OVX drops out of the Crisis Pressure Index, its 20% is shared out and the remaining three inputs scale up: the 30 / 25 / 25 split becomes roughly 37 / 31 / 31. When this happens, the affected index in /api/index carries a degraded block naming each redistributed component and its nominal weight, so the renormalization is visible rather than implied by the shifted numbers.

This is a different case from the Escalation Forecast’s liquidity floor described above, where the contracts exist but trade thin. There the number is still shown, just flagged low-confidence, with no weight collapse. Redistribution fires when an input is genuinely absent or stale, not merely quiet. If every input for an index is missing, the tick still writes, but no component carries weight, the composite is zero and indexHealth drops to low-confidence, which is the field to gate on: a published value is not evidence that any input was available. When every input is only stale, the last-known values are kept rather than collapsing the composite to a false zero.

The threshold is 30% of nominal weight. indexHealth stays “fresh” while less than that has dropped out, so a single 25% input standing down renormalises the rest and the reading is still published as fresh. That is deliberate, since a composite of three healthy inputs is worth more than no reading at all, but it means indexHealth alone does not tell you every input was present. The per-component list carries each input’s own weight and stale flag, and is the place to check which ones actually contributed: /api/index.

Bands, shared across both indices.

The bands carry the same emotional register; only the meaning of being at 80 differs. Crisis Pressure at 80 says a crisis is happening; Escalation Forecast at 80 says markets price a bad outcome as likely, across the mixed horizons described above.

The ± figure. Each index is shown with a small ± value (for example 94 ± 3). It is a dispersion band: the weighted standard deviation of the component scores, multiplied by 0.4 and then clamped to the 2–15 range. The scaling matters when you read it: a band of 2 does not mean the components agree to within 2 points, it means their weighted standard deviation is under 6.25 points. The deviation is taken over effective weights, so a component that has stood down is left out of it entirely. Read it as “how much the inputs disagree right now,” not as a statistical confidence interval. A small value means the components point the same way; a large one means the composite is averaging across divergent signals.

  1. 019Calm
  2. 2039Watchful
  3. 4059Elevated
  4. 6079High
  5. 80100Extreme

Known limitations.

  • Forecast inputs are thin. The Escalation Forecast runs on three prediction-market venues (Polymarket, Kalshi, and Manifold) plus the Brent–WTI front-month spread. Hormuz contracts trade at modest volume relative to broader political markets, and Manifold's mana is play-money rather than dollar-backed. Combined lifetime volume across the three venues rarely nears the liquidity floor above, so the per-venue volume floor described there is the control that actually stands a thin venue down.
  • OVX is a state input. CBOE OVX is 30-day implied volatility on options over USO, the United States Oil Fund, which tracks near-month WTI. It is not a Brent instrument, and its VIX-style method prices a strip of out-of-the-money options, not at-the-money ones. Sourced directly from CBOE, with Yahoo Finance and FRED as fallbacks. It sits inside the Crisis Pressure Index rather than the forecast index: spot vol is overwhelmingly reactive, measuring repricing that has already happened, not forward expectations. Term structure (front-month vs 6-month) would be a genuine forecast input, but no free public source publishes it.
  • Pre-2022 history is state-only. Polymarket did not exist before 2022 and Manifold dates to 2022. Historical backfill of the Escalation Forecast would have a structural input gap; we plan to backfill the Crisis Pressure Index to earlier crises (1990, 2003, 2019) but leave the forecast index without pre-Polymarket history rather than synthesize a proxy.
  • Calibration in progress. The weights, normalization curves, and rails published here are v0.6.0. Every change is recorded in the changelog with both live-published and retro-computed values preserved. The v0.1 methodology page is archived at /methodology/v0.1 for historical reference.

AI assistance in the daily brief.

The bullets and situation summary on the daily brief (rendered on the homepage and at /briefs/[date]) are drafted with AI assistance. A scheduled function calls a large language model with the structured indicators visible on this site (transit counts, Brent and WTI prices, the Hormuz Index components, indexed events from the last 24 hours) and asks for three bullets and a single situation paragraph in a fixed JSON shape.

What the model sees: only the figures and event headlines that already appear elsewhere on this site. The prompt forbids inventing numbers, paraphrasing them ("a handful", "about sixty"), or claiming agreement between divergent indicators. If the figures shown elsewhere on the page change, the brief will not silently disagree; the same source-of-truth feeds both surfaces.

What the model does not see: live web search, social-media chatter, news articles beyond the titles in our indexed event feed, external commentary, or any data not present on this site. It cannot cite a source it has not been shown. When the underlying event feed is unsourced or the model output fails JSON validation, the brief falls back to a rule-based summary; the “Indicative summary” chip on the page surfaces that case explicitly.

Briefs flagged “AI-assisted” on the page carry the same label in the NewsArticle JSON-LD so downstream readers (search engines, AI overviews, aggregators) see the disclosure too. Briefs flagged “Editorial” are human-written; briefs flagged “Indicative summary” are rule-based fallback prose. The provenance is recorded per-brief in Firestore and exposed via /api/v1/briefs.

Disclosure.

The publisher does not trade on either index, hold positions sized to its movement, or use it for personal investment decisions.

Neither index is a benchmark within the meaning of EU Regulation 2016/1011 (Benchmarks Regulation) and is not licensed for use as a reference rate for any financial product.

Both indices are informational only and not investment, financial, legal, or tax advice. Embeddable versions carry this disclaimer server-side and cannot be stripped by the embedding site.

Methodology changelog →

What we count.

The headline transit number (the count that drives status, throughput, and the lede) comes from the IMF PortWatch chokepoint6 dataset, an attributable daily feed built on global AIS signals via the Oxford / UN Global Pulse partnership. Every other AIS-derived figure (live presence overlay, stranded count, per-port congestion, tankers gone dark, sanctioned- vessel join) derives from a Persian Gulf bounding box of live AIS positions, plus a tighter inner zone for the AIS-dark count and four named ports for per-port congestion. The diagram below shows where the AIS-derived measurements apply.

Strait of HormuzBandar AbbasJebel AliFujairahSohar28°N22°N54°E ↔ 60°EIranUAE / OmanAIS-dark filter zone
  • Outer bbox · AIS subscription window
  • AIS-dark filter zone · 24–28°N, 55–58°E
  • Strait of Hormuz centroid · 26.566°N, 56.25°E
  • Tracked ports · 10–12 km radius each
Illustrative · not GIS. The bounding box and the AIS-dark filter zone are exact (defined in fetchShipPositions.ts and computeAisGaps.ts); coastlines are stylized. The four ports are the named locations for which portCongestion/{id} documents are written hourly.

Markets & risk pricing

Prices, premiums, and odds: what the market thinks about the disruption right now.

Brent and WTI prices

Every 10 minutes

SourceIntraday front-month futures contracts (ICE Brent, NYMEX WTI) via Yahoo Finance chart data, with continuous quotes as fallback and EIA daily closing prices as backstop

Intraday front-month futures contracts, with continuous quotes used only when explicit-contract resolution comes back empty; the prior upstream (Stooq) retired its continuous-futures symbols on 2026-06-09 and was replaced the same day. The published 24-hour change is a trailing figure computed from stored hourly history against a median-of-bracket anchor, not a session move. EIA publishes once-daily closes for canonical citation and is a backstop that writes only when the live feed goes stale over 2 hours.

Reference →

US gas prices

Hourly refresh; upstream publishes once daily

SourceAggregated US state-by-state regular-grade gasoline averages

Per-state regular-grade averages plus a national mean across the 50 states + DC. Only the regular-grade column is extracted.

Prediction-market odds

Every 15 minutes

SourcePolymarket (gamma-api.polymarket.com) + Kalshi (trade API v2) + Manifold (api.manifold.markets) public read APIs

Active markets pulled from each venue, filtered by a relevance keyword set covering Hormuz / Iran-conflict / oil-shock terms with a hard exclude list for sports and entertainment substring collisions; top 30 by dollar-volume retained across venues. Manifold volume is reported in mana and converted to USD-equivalent at the conservative 100:1 rate Manifold itself uses for charity redemption. Kalshi was dropped at v0.3.2 (2026-05-27) after an audit found zero traded Iran/Hormuz contracts in its catalogue, and re-included at v0.4.0 (2026-06-10) after Kalshi listed heavily traded Hormuz series; see the changelog for both audits. Implied YES probability is labelled "market price" because the bull/bear read depends on question framing: high YES on "regime fall" reads bearish; low YES on "Hormuz reopens" reads bearish.

Reference →

War-risk insurance multiple

Manual; refreshed when new pricing surfaces

SourceEditorial reading of trade-press reporting (Splash247, Lloyd's List, gCaptain, Reuters)

The "Nx normal" multiple and the dollar band ($250,000 peace baseline to about $10M per voyage during the closure, per named trade-press outlets) are estimated separately from different reported figures, not one derived from the other, so the two will not divide exactly. London-market war-risk pricing is not published as machine-readable data, so both carry an editorial uncertainty band. The figures were last re-verified on 2026-08-05 against Marsh estimates carried by S&P Global and Al Jazeera, and against Lloyd's List reporting of quotes topping $10M for a single VLCC transit. The multiple is set at the bottom of the reported band rather than its midpoint. Note that the index score curve tops out at 16x, so the current multiple leaves this input pinned at its ceiling until rates roughly halve.

Trade impact (oil/LNG at risk, daily cost)

Quarterly (EIA publication cycle)

SourceEIA World Oil Transit Chokepoints reference figures

Two different oil statistics get confused here, so we state both. Under normal conditions Hormuz carries about a fifth of global oil consumption, and about a quarter of global seaborne oil trade (EIA puts 2024 at "more than one-quarter"). The 25% figure published on this site is the seaborne-trade share; the API field worldOilAtRiskPct reports that same seaborne share. The LNG figure is about 20% of global LNG trade, almost all Qatari. The $4B/day cost figure is our own estimate of price-spike pass-through plus reroute cost plus insurance load; it is not the gross value of the cargo, which at current Brent is closer to $1.51B/day, and it is not an EIA number. Shocks of this kind are not linear in real-economy effects, which depend on inventory, demand response, and bypass-pipeline utilization.

Reference →

Transits & vessel traffic

Daily transit count comes from IMF PortWatch: authoritative, attributable, survives AIS outages. AIS contributes a live presence overlay plus several derived metrics that need per-vessel positions PortWatch does not provide.

Daily transit count

Underlying data publishes Tuesdays 9 AM ET; we re-fetch daily 14:00 UTC

SourceIMF PortWatch (chokepoint6 dataset, public ArcGIS feed)

Daily count of vessels that traversed the Strait of Hormuz, by ship class. Built on global AIS signals from ~90,000 ships via the IMF / Oxford / UN Global Pulse partnership. Methodologically transparent and IMF-attributed; this is the dashboard's authoritative throughput backbone. Survives any outage in the live AIS feed. PortWatch publishes weekly on Tuesdays. Its newest record carries a roughly two-day lag, so the freshest Hormuz day is about two to nine days old depending on where you are in the publish cycle. The Hormuz layer now publishes on the same lag as its other chokepoints; it ran about three days further behind them until 2026-08-04.

Reference →

Throughput (% of pre-crisis typical)

Daily 14:00 UTC

SourceDaily transit count ÷ final-pre-crisis-year PortWatch median (~73/day)

Computed against a stable peacetime baseline: the median across the final 365 pre-crisis days (2025-02-28 through 2026-02-27), fetched as a fixed date-bounded window so the sample cannot shrink over time. We deliberately do NOT use a 30-day rolling baseline: once a closure outlasts the window, the rolling baseline collapses to match the disrupted state and the dashboard would silently flip "closed" to "open" while the strait is still closed. The pre-crisis median is the right anchor for a sustained-crisis dashboard. Falls back to a rolling baseline only during cold-start before PortWatch backfills.

Live concurrent presence (AIS overlay)

Every 15 minutes

SourceLive AIS position feeds, Persian Gulf bounding box

Best-effort live ticker, shown as a "N live" sub-line on the homepage when the AIS feed is fresh, hidden when stale (>30 min) or down. Does NOT drive status, throughput, or the verdict; those read PortWatch. AIS counts vessels currently broadcasting transit status inside a Persian Gulf bounding box (lat 22–28, lng 54–60). Multi-hour silent windows can occur. Military vessels often run dark; small fast-attack craft are not consistently captured. SERIES BREAK 2026-07-20: the counting basis switched from a 4-hour union of sightings to a 30-minute active-sighting window. The concurrent transit count steps down by roughly 45 percent at the cutover, the largest step of any AIS series; points before that date used the old basis and cannot be restated. SECOND SERIES BREAK 2026-07-30: the AIS scraper stopped taking one thinned request for the whole bounding box and began tiling it so each tile is saturated. This break runs the other way: counts step up, roughly 3.4x on total across the box. Counts before 2026-07-30 were a floor, not a census, and cannot be restated for the same reason as the first break: the underlying collection holds current state with no per-hour archive. Do not trend across either break.

Port congestion

Every 30 minutes

SourceAIS-derived count of vessels within ~10 km of named ports

Counts vessels in shipPositions whose coordinates fall within a 10–12 km radius of Fujairah (UAE Indian-Ocean side, ADCOP terminus), Sohar (Oman alt-berthing), Bandar Abbas (Iran main strait port), or Jebel Ali (Dubai container hub). Anchored vessels count as congestion; transiting vessels excluded. Yanbu (Saudi Red Sea) sits outside our bounding box and cannot be tracked from this feed. SERIES BREAK 2026-07-20: the underlying AIS count switched from a 4-hour union of sightings to a 30-minute active-sighting window, stepping the wider AIS population down by roughly 20 percent at the cutover. SECOND SERIES BREAK 2026-07-30: the AIS scraper stopped taking one thinned request for the whole bounding box and began tiling it so each tile is saturated. This break runs the other way, stepping counts up by roughly 3.4x on total and far more at busy anchorages, Fujairah 3 to 84 and Jebel Ali 13 to 76. Counts before 2026-07-30 were a floor, not a census, and cannot be restated: the underlying collection holds current state with no per-hour archive. Do not trend port-congestion counts across either date.

Stranded-vessel time-series

Hourly buckets, written every 30 minutes

SourceAIS-derived running count of anchored vessels in the bbox

Hourly snapshots of the stranded count. Anchored is an inferred read, not a broadcast navigational field: a vessel counts as anchored once it has moved less than roughly 500 meters between position reports spaced roughly 15 to 18 minutes apart, and as transiting otherwise. This inference cannot distinguish a vessel formally at anchor from one drifting, loitering, or holding under instruction; it only measures displacement. The homepage sparkline shows the span it currently has data for on the active counting basis, which grows back to 7 days after a basis change. Hourly cadence resolves daily news beats; finer-grained changes are visible at /api/v1/stranded. SERIES BREAK 2026-07-20: the counting basis switched from a 4-hour union of sightings to a 30-minute active-sighting window. The stranded series steps down by roughly 13 percent at the cutover; points before that date used the old basis and cannot be restated. SECOND SERIES BREAK 2026-07-30: the AIS scraper stopped taking one thinned request for the whole bounding box and began tiling it so each tile is saturated. This break runs the other way, stepping counts up by roughly 3.4x on total. Counts before 2026-07-30 were a floor, not a census, and cannot be restated for the same reason. Do not trend across either break.

Tankers gone dark (AIS gap)

Computed every 30 minutes

SourcePersistent vesselTracker collection (cumulative AIS sightings) × strict filter

A tanker "going dark" is genuinely ambiguous: equipment failure, GPS spoofing, deliberate evasion, or simply leaving the bbox can all produce the same observation. The filter requires (1) type = tanker, (2) total sightings ≥ 50 to confirm prior active broadcasting, (3) last position inside the core area (lat 24–28, lng 55–58) so vessels that sailed out are excluded, (4) last seen 3–24 hours ago. Strict, biased toward false-negatives. Homepage and /api/v1/ais-gaps show count + 7-day baseline; the per-vessel dark-fleet identities are in the premium vessel-intelligence API.

Sanctioned vessels in transit

OFAC SDN refreshed weekly; cross-join run every 15 minutes

SourceOFAC Specially Designated Nationals list × live AIS positions

OFAC SDN CSV filtered to vessels (~1,500 entries), with IMO and any "a.k.a." / "f.k.a." aliases extracted from the freeform remarks column, joined against shipPositions by IMO when available, normalised name otherwise. Match strategy biased toward false-negatives, because common names ("Glory", "Victoria", "Mercury") are shared across dozens of unrelated hulls. About half of SDN vessel entries state the sanctioned hull's own MMSI in their remarks; where they do, a name match whose MMSI contradicts it is rejected, as is one whose known IMO contradicts the entry's. On 2026-08-01 that test rejected 16 of 34 name matches, including a Dutch-flagged ALEXANDRA matched against an SDN record naming a Liberian-flagged hull. A name match that survives is still weaker evidence than an IMO match, and matchedBy says which you are looking at. The homepage block is muted at zero hits and the free summary API returns a count without names; the named per-vessel manifest is in the premium vessel-intelligence API. Many shadow-fleet vessels rename to evade the SDN list; we will under-count. The premium per-IMO dossier additionally merges the UK Sanctions List (FCDO/OFSI, ~650 designated ships), which is natively IMO-keyed and adds owner/operator, flag, tonnage, and a per-ship Date Designated. UK data contains public sector information licensed under the Open Government Licence v3.0.

Reference →

Lane breakdown (N / S)

Every 15 minutes (matches the AIS feed)

SourceLat-based classification of in-transit vessels against the IMO Traffic Separation Scheme

Vessels marked status=transit are bucketed by latitude inside the chokepoint window (lng 56.0–57.4°E, lat 25.7–26.9°N): ≥26.5°N = Northern lane, ≤26.3°N = Southern lane, the band between is treated as the TSS separation buffer. Without course-over-ground on every AIS position this is a static lane assignment, not a direction-of-travel inference, but in a TSS the lanes ARE the direction, so "N lane" reads as inbound traffic and "S lane" as outbound, matching the IMO designation at Hormuz. Exact lane geometry is published in BA chart 2858 / INT 728; we approximate with editorial lat bands.

Per-vessel risk band

Every 30 minutes

SourceRules engine joining vesselTracker × sanctionedTransits × current AIS-dark list × MMSI flag-of-convenience × broadcast-IMO validity

Each active vessel (lastSeenAt within 24h) is bucketed High / Moderate / Low by a transparent rule set: High = OFAC SDN match, OR flag-of-convenience tanker that is currently AIS-dark in the core area, OR a vessel broadcasting a spoofed IMO that is also AIS-dark or an FOC tanker. Moderate = currently AIS-dark, OR FOC-flagged tanker on its own, OR a spoofed IMO on its own. Low = everything else. Flag-of-convenience is derived from the first three digits of the MMSI (the ITU-T M.585 Maritime Identification Digit), restricted to the open registries OFAC/EU/Lloyd's-List investigative reporting consistently names: Panama, Liberia, Marshall Islands, St Kitts, São Tomé, Gabon, Cook Islands, Cameroon, Côte d'Ivoire, Togo, Palau, Bahamas. Greek and Singaporean flags are NOT treated as FOC despite open-register critics. A "spoofed IMO" is a well-formed 7-digit number in the vessel's broadcast IMO field that fails the IMO check-digit algorithm: a deliberate-deception signal (fabricating an identifier), resolved by the vessel-identity enrichment pass. It is only a soft signal on its own (guarding against a rare source data-entry error) but lifts an already-flagged vessel to High. This is a rules engine, not an ML model: there is no opaque score, no learned weighting, no behavioural inference beyond these inputs. Ownership and beneficial-ownership signals are still out of scope; expect a high-band count meaningfully lower than commercial maritime-AI products that fuse those inputs. Aggregate counts on the homepage; per-vessel scores and pills at /vessels; raw scores read off vesselRisk/{mmsi}. The full population as one ranked, worst-first screen (every hull with its band, the reason codes behind it, and OFAC/UK sanctions matches) is the premium shadow-fleet risk screen at /api/premium/hormuz/risk-screen.

Industry response

How the carriers and pipelines are reacting in public: postures, surcharges, and rerouted capacity.

Carrier suspensions

Manual, and reviewed from time to time rather than on a schedule. A weekly job refreshes the timestamp; it does not re-check the carriers. Each row carries the date it was authored, which is the date to read.

SourceEach carrier's public customer-advisories page (linked); cross-checked against trade press (Splash247, Lloyd's List, gCaptain, Reuters)

Tracks the nine largest container carriers by global TEU capacity. "Status" reflects each carrier's declared posture for Strait of Hormuz transit. "Surcharge $/TEU" is an editorial estimate based on each carrier's announced base surcharge and current bunker pricing on the Cape route; values are not directly quoted from the linked carrier page, which typically presents the policy without a single dollar figure. Treat as indicative, not contracted.

Pipeline bypass capacity

Annual (EIA publication cycle)

SourceEIA petroleum infrastructure data and country analyses

Three pipelines route Gulf crude around the strait: Petroline (Saudi → Yanbu, 5M bpd), ADCOP (UAE → Fujairah, 1.5M bpd), Goreh-Jask (Iran → Jask, ~0.35M bpd nameplate, currently operating at a fraction of capacity). Combined nameplate bypass ≈ 7M bpd against a normal Hormuz flow of 17M bpd; effective utilization is lower.

Reference →

Inventories & reserves

Where the buffer sits, and how it's drawing down: the slow-moving counter-pressure to a fast-moving disruption.

Strategic Petroleum Reserve (US)

EIA publishes weekly; we re-fetch daily 11:00 ET

SourceEIA Weekly Petroleum Status Report

The US SPR sits in salt caverns at four sites along the Gulf Coast. The doc carries the 4-week change so spike-vs-baseline reads correctly. Non-US holders (China, Japan, South Korea, EU, India) on the SPR page are editorial best-estimates; most countries do not publish stockpile data weekly.

Reference →

Cushing crude oil stocks

EIA publishes weekly; we re-fetch daily 11:30 ET

SourceEIA Weekly Petroleum Status Report

Cushing, Oklahoma is the WTI delivery hub. Inventory swings here track the North-American crude balance independent of the Gulf-Coast / SPR picture. Pairs with the Brent–WTI spread to indicate whether disruption is global or American-specific.

Reference →

Events & narrative

What happened in the past 24 hours, and what it means: sourced events plus a programmatic daily summary.

War events timeline

Live feeds every 15 minutes; the curated set is hand-written and a weekly job only refreshes its timestamp

SourceCurated editorial set + Google News RSS + gCaptain RSS + USNI News RSS + Iranian state media (IRNA, Mehr News, Press TV). GDELT plumbed in as a redundant supplement when its rate-limit allows.

Each event carries a sourceUrl that links to the originating outlet. Tehran-state framings (IRNA / Mehr / Press TV) are clearly labelled in the sourceName so readers can interpret the framing. A strict keyword filter applies to state-media feeds: every article from those outlets mentions Iran by default, so we require an explicit Hormuz / chokepoint / maritime / oil term to keep the timeline focused. Per-source cap of 6 events per ingestion run prevents a single fast-publishing feed from blanketing the timeline.

Daily brief

Daily at 12:00 UTC, with extra runs during a crisis

SourceEditorial summary of the indexed war events and price moves from the prior 24 hours

Generated programmatically; not edited by hand. When the underlying event feed is mock or unsourced, the prose summary is suppressed and only the bullets render, so the front page never carries a confident crisis narrative built on synthetic data.

Supplementary feeds

A subset of indicators is derived from third-party maritime and financial data aggregators that publish under their own terms. We don't redistribute the underlying datasets, only the derived counts, aggregates, and freshness checks computed from them. Specific upstream sources are kept private at our discretion: naming them risks being blocked, and several have terms that don't authorize republication of the raw data. If you're a journalist or researcher who needs to verify a specific number, email hello@straits.live and we'll walk you through the derivation.

Port-congestion snapshots (Fujairah, Sohar, Bandar Abbas, Jebel Ali)

Hourly

SourceAIS-based maritime data aggregator · upstream source kept private

Anchored / berthed counts per port. We compute the snapshot ourselves; the underlying per-vessel records are not redistributed.

Vessel-mix and recent-vessel summaries

Hourly

SourceAIS-based maritime data aggregator · upstream source kept private

Per-class transit counts (tanker / cargo / military / other) and recent named-vessel lists, used to keep the live picture rendering when the live position feed is in a silent window.

Per-vessel type resolution (Transits by type)

Every 30 minutes, resolving a bounded batch of vessels per run

SourcePublic vessel-database pages · upstream source kept private

Our position feed carries only a coarse vessel-class marker that distinguishes tanker from cargo and nothing else, so it cannot identify a warship. We resolve a per-vessel type by MMSI against a public vessel database and prefer it over the marker; vessels not yet resolved fall back to the marker and read as other. Two consequences worth stating plainly. The military count is a floor, not a census: naval vessels routinely transit with AIS switched off, and a vessel only counts as military once its type has been resolved. And because resolution is incremental, the tanker / cargo split reflects a mix of both methods rather than one uniform classification.

Chokepoint comparison (Hormuz vs. Suez / Bab el-Mandeb / Malacca / Panama)

Daily

SourceIMF PortWatch chokepoint dataset (public page, parsed by our scraper rather than via an API)

PortWatch publishes daily transit counts for every major maritime chokepoint. We pull the comparison set so the dashboard can show Hormuz against its peers.

Tehran open-market USD/IRR rate

Hourly

SourceOpen-market currency aggregator · upstream source kept private

A continuously-quoted open-market mid-rate. Useful as a high-frequency signal of regime currency stress; not a published banking rate.

Bunker fuel indicative pricing

Daily

SourceMaritime fuel pricing aggregator · upstream source kept private

Daily VLSFO indicative pricing for the Fujairah bunker market. Spot indicator, not an exchange-cleared price.

When figures look wrong.

Feeds drop. Vessels spoof their AIS. Upstream sources change their publishing format and a feed breaks. The page is built to fail visibly rather than silently: affected indicators flip to a stale or suppressed state and the data-health chip on the section tells you which.

If a number still looks wrong after that, it usually is. Reply to any email or send a note to hello@straits.live with the section name and what looks off; corrections get pushed the same day.

← Back to the Strait of Hormuz live update About → Glossary →