Methodology
DEAD RECKONING is an instrument, not an accusation. It measures where aircraft report degraded navigation integrity, aggregates that signal over space and time, and shows it with its uncertainty attached. This page explains exactly what the signal is, how it is computed, and, just as important, what it cannot tell you.
What NIC is
Every ADS-B–equipped aircraft broadcasts a Navigation Integrity
Category (NIC), an integer from 0 to 11,
alongside its position. NIC states how tightly the aircraft's own navigation
system can bound the error on the position it is transmitting. It is paired
with a radius of containment (rc, in metres). High NIC
means a small, trustworthy containment radius; low NIC means a large one.
When GNSS (GPS, Galileo, GLONASS, BeiDou) is jammed or spoofed, receivers
lose the ability to bound their error, and NIC falls, often all the way to
0 ("integrity unknown"). Many aircraft in one area reporting low
NIC at the same time is the fingerprint of interference in that
airspace. Our sample day shows the containment ladder cleanly:
| NIC | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 |
|---|---|---|---|---|---|---|---|---|---|
| median rc (m) | 8 | 25 | 75 | 186 | 371 | 926 | 1852 | 3704 | 7408 |
The inference rule
Interference is inferred from multiple proximate aircraft, never a single report. The pipeline:
- Streams a full UTC day of open ADS-B traces from adsb.lol.
- Keeps only airborne positions that carry a NIC value (ground positions and non-positional records are dropped).
- Bins each position into an H3 resolution-4 hex (~1,770 km² per cell).
- For each aircraft in each hex, marks it degraded if the
majority of its NIC reports there are
nic ≤ 6(containment radius ≳ 1 km). - Computes each hex's
bad_ratio= degraded aircraft ÷ unique aircraft.
Thresholds & their sensitivity
The degraded threshold nic ≤ 6 is chosen because NIC 6
corresponds to a containment radius of roughly 1 km, the point at which a
position is too loose to trust for navigation. NIC 7 and above (rc < ~370 m)
are treated as healthy.
nic = 0 counts as degraded.
On the reference day the degraded signal is dominated by nic = 0
reports (~85% of all degraded points): aircraft dropped to "integrity
unknown," which is the expected physical signature of a receiver
under interference that can no longer bound its own error. Excluding it would
throw away the strongest evidence of GPS denial, so it is folded in
deliberately. Spatially this behaves as a real signal should: it concentrates
in known interference zones (Baltic/Kaliningrad up to 1.0) and is near-absent
over a quiet control (central US ~0.10 max).
Sensitivity (kept on the record): the degraded-point
fraction is 5.98% including nic = 0 vs
0.87% excluding it. Sample-day figures, so the map is
largely a nic = 0 density surface, and you should read it as
one. A per-hex strict view (1 ≤ nic ≤ 6) is a planned
toggle to show that band directly. All thresholds live in a single config
file and are versioned with the data.
Confidence & the honesty rule
Every hex ships with its unique-aircraft count and a confidence tier: high (≥10 aircraft), medium (5–9), and insufficient (<5). Hexes below the minimum-aircraft floor are never rendered as a value or a confident color. On the map they appear as a dim diagonal hatch (the Low-sample cells toggle). This is the whole point of the instrument: you can always tell "no interference" from "no coverage."
That distinction only works if coverage is visible: a dark cell could mean "watched and calm" or "nobody was looking." So measured-but-quiet airspace draws a faint watched-airspace carpet (the Quiet coverage toggle, on by default). It is a whisper that never competes with a real bloom, but it turns the black background into an honest three-state reading: quiet (watched, calm), degraded (the signal), hatched (too few aircraft to judge).
The sensor-desert paradox
There is a fourth state, and it is the most important caveat in the whole instrument. We measure interference where civil aircraft fly, which is systematically not the airspace that is closed or avoided. When airspace is closed or widely avoided the sky empties and the sensors leave with the traffic, so the worst jamming can sit inside a dark zone that means "nobody was looking," not "all clear." We see the edges of such airspace, not its interior. The overlay describes the instrument's blindness (an airspace-status fact), not the reasons behind it.
The Airspace context overlay (on by default) keeps that honest. A violet dashed outline with a faint wash (a hue never used for signal) marks airspace that is closed to civil aviation (e.g. Ukraine, since Feb 2022), of reduced coverage (e.g. Russia, widely avoided and thin on volunteer receivers), or a known test area (US ranges where GPS testing is recurring and announced). Each zone card leads with the regulatory fact and its source; click a zone to read it. So the fourth reading is outlined: the instrument is blind here, and that blindness is itself information. Zone outlines are drawn from Natural Earth boundaries as context, not precise airspace geometry.
Not every dark cell is a zone. Oceanic and remote-region darkness reflects terrestrial ADS-B receiver range (roughly 250 nm offshore before line-of-sight runs out) and volunteer-receiver sparsity, not airspace status. The traffic-density Coverage view is the honest instrument for where the sensors are; the zone layer is reserved for regulatory / conflict causes only. A dark ocean is a coverage fact, not a closed zone.
A worked example: same signal, three meanings
The instrument's core lesson is that the reading is not the analysis. On any given day, three places can look similar on the map and mean entirely different things, which is why context lives in the region profiles, not the color scale.
- Kaliningrad & the Baltic: a chronic, wide-area degradation beside an active conflict; European reporting attributes it to Russian electronic-warfare activity. Here degraded NIC is the baseline, not the anomaly.
- Central US: a quiet control. This is what "clear" looks like on the same sensor, and it's why a lit-up region elsewhere is meaningful rather than an artifact of the method.
- US Southwest (White Sands / NTTR): an identical NIC-degradation signal to a hostile jamming zone, but benign: scheduled, publicly NOTAM'd GPS-test exercises. The sensor cannot tell the two apart; only the context can. This region is included deliberately as the interpretive control.
Validation
Two checks keep this honest:
Internal (quantified). On the reference day, known chronic zones light up as expected while a deliberate control stays dark:
| Zone | cells ≥5 aircraft | max degraded ratio |
|---|---|---|
| Kaliningrad / Baltic | 121 | 1.00 |
| Eastern Med / Cyprus | 181 | 0.67 |
| Central US (quiet control) | 212 | 0.10 |
Signal and background separate cleanly; the method isn't lighting up everywhere aircraft fly.
External (independent reference). The persistent hotspots this archive surfaces (the Baltic/Kaliningrad corridor and the eastern Mediterranean) are the same regions independently mapped as chronic GNSS-interference zones by live trackers such as GPSJam and Flightradar24. Those tools show current conditions; you can compare any date directly on GPSJam. A dated side-by-side cross-check for 2026-07-13 found agreement on every major hot zone: Baltic/Kaliningrad, the Black Sea western rim through Istanbul and eastern Turkey, Moscow-area spots, and the eastern Mediterranean. That held despite the two projects drawing on different feeder networks (adsb.lol vs ADS-B Exchange). Two independent pipelines agreeing on the same date is strong corroboration; the writeup and caveats are in docs/validation/2026-07-13. It is visual corroboration between two ADS-B-derived estimates, not validation against ground truth.
Baselines & anomaly
Chronic zones are interesting; change is more interesting. For each
hex we compute a rolling baseline (mean and standard deviation of
bad_ratio over up to 28 qualifying days) and express each day as a
z-score: how many standard deviations above its own normal the hex sits. The
default map view is this anomaly score; a toggle shows the raw ratio. A hex
needs at least 7 qualifying days of history before it earns a baseline, so
early in the archive many hexes show raw values only. The baseline uses the
window of available days around each date, which suits a retrospective archive
rather than a real-time alarm.
What this instrument cannot see
- Coverage bias. The signal exists only where aircraft fly and where ground receivers hear them. Open ocean, closed airspace (e.g. much of wartime Ukraine and the Black Sea), and receiver-sparse regions read as no data, not as no interference.
- Equipment & multipath false positives. Old or faulty avionics, and dense-terrain multipath, can lower NIC without any interference. The multiple-aircraft rule suppresses most of this, but a single anomalous hex is never proof.
- Cause. NIC degradation shows that integrity dropped, not why or by whom. Attribution lives only in the region context profiles, with sources, and is labeled as analyst interpretation, not asserted by the map.
- Spoofing vs jamming. v1 measures integrity degradation broadly; distinguishing spoofing (false positions) from jamming (lost positions) is future work.
Verification & quality
The instrument is built to be checked, not trusted on faith.
- Independent review passes. Every batch goes through separate reviews for code correctness, content sourcing, visual design, and a pre-publication audit before it ships. No pass reviews its own author's summary.
- Automated tests with regression guards. 36 tests lock the honesty rules in place: the majority-rule boundary, the baseline math, parser filtering, draft gating, and a check that every listed day resolves to a present, well-formed artifact.
- Deterministic pipeline. Re-running a day regenerates its file byte-for-byte, and every derived aggregate is reproducible from the dailies.
- Sources are link-verified. Region, event, and airspace sources are checked live, and claims are corrected before content clears draft.
The external cross-check against independent instruments is covered under Validation above.
Reading the map honestly (design semantics)
The color choices are part of the method, not decoration. A few rules make the map trustworthy:
- Colorblind-safe, verified per theme. Every meaning-bearing ramp uses colorblind-safe palette families and is verified for monotonic lightness on both the light and dark grounds; formal per-deficiency simulation is on the roadmap.
- Saturated red means one thing. Alarm-red is reserved for extreme anomaly and appears nowhere else, so a red cell is never ambiguous.
- Insufficient data is never a value. Cells below the aircraft floor render as a hatch, distinct from both quiet and signal. Low sample never earns a confident color.
- Context is outlined, never filled. Airspace zones and event markers use outlines and markers in a hue never used for signal, so annotation can never be read as data.
- The numbers stay honest. Ramp scaling can be nonlinear for legibility, but the value shown on hover or click is always the true number.
Time, data & licensing
Everything is UTC; the source dumps are UTC days. Source flight data © adsb.lol feeders and partners, published under the Open Database License (ODbL) 1.0. Our per-day aggregates are a derivative database, also published under ODbL; only aggregates are retained; raw traces are deleted after processing. The project code is MIT. Basemap © OpenStreetMap contributors via OpenFreeMap.
← back to the map