Case file 01 · Data · Journalism
Under Fire
Six years of rocket, missile and drone alerts across Israel, turned into an interactive data story: timelines, heatmaps, salvo arcs across the map, and records. Just the data, no commentary.
- Year
- 2026
- Role
- Solo: data pipeline, design, build
- Read
- 3 min
Context
A public-interest data project covering six years of rocket, missile and drone alerts across Israel, built on the RocketAlert.live record from January 2020 onwards. The framing was a hard rule from the start: no blame, no policy, no commentary. Just the patterns, and a clear note of where every number comes from.
The problem
Alerts are published one event at a time: a timestamp, a place, a siren. At that level you can see that something happened, but not the rhythm of it, where it concentrated, or how the picture changed over six years. Making that readable came with real limits. The site is static, so the browser can't carry 54MB of raw alerts or add them up on the fly. Working out where an alert came from is an estimate based on location and timing, and it has to be labelled that way. And the worst case is also the one that matters most. October 7 alone produced nearly 4,000 alerts, so anything that draws one element per alert breaks exactly where the data is most important.
What I built
A hub of pages that each load on their own: a six-year timeline you can filter by actor, monthly fronts, a daily calendar, a 24-hour polar clock, origin arcs, records, a scroll-driven story map that flies between six fronts, a minute-by-minute replay of October 7, a live 14-day feed, and a map of the thirty Home Front Command regions you can hover over. Python boils the master record down to nine small summary files, about 500KB in total, before anything reaches the browser. Behind that, a scheduled job runs every 30 minutes using only Python's standard library. It pulls new alerts, removes duplicates, attributes them, rebuilds every summary and commits the result, so a fully static site keeps itself up to date.
Decisions & iterations
The first version was one long page that loaded every chart at once. Splitting it into separate pages was the most important architectural decision in the project, and it made every chart after that cheap to add. The salvo animation draws at most 80 arcs however big the real salvo was, and the label carries the true count. Attribution needed the same kind of rethink. Matching each alert on geography alone agreed with the historical labels only 67% of the time, so I replaced it with salvo clustering plus automatic detection of barrage days, which got to 93.1%. I also deleted the fake terminal that used to make you press “Run” before each chart. On a site whose whole argument is that the data is real, theatrical code was costing credibility.
Outcome
Live at under-fire.org and updating itself. The master record runs from January 2020 to today and has passed 160,000 alerts, after backfilling a 17,548-alert gap in the spring and removing 235 duplicate rows found in the merge. The pre-launch audit cut page weight by 98%, from 5.9MB of PNGs to 115KB of WebP. Every figure that could go out of date is read from the summary file when the page loads, not written into the HTML. So the numbers on the page are always the numbers in the file, which matters on a site that's asking to be trusted.