Skip to content

Case study 01

Night Watch Ukraine

Timeline: 2026

Night Watch Ukraine alert map and data visualization interface

The vision

Night Watch Ukraine is an OSINT tool that combines public alert data from multiple providers and visualizes it on an interactive map. It supports live alerts, historical replay, and activity analysis in both 2D and 3D using MapLibre and deck.gl.

The source data varies heavily in structure and precision. One provider may report an entire oblast while another reports a raion, hromada, or settlement inside it. The ingestion pipeline normalizes these records while preserving their original payloads, timestamps, locations, and sources. A stable content fingerprint is derived for each observation so repeated records can be identified and deduplicated reliably.

Building a useful heatmap from overlapping regions required a separate spatial model. Each region is converted into grid samples. Samples at shared coordinates are merged, and their alert counts and active durations are accumulated before the final intensity is normalized. More precise child regions replace broader parent regions in the same area to avoid double-counting.

The visualizations support both administrative regions and a hexagonal grid in 2D and 3D. The hex-grid resolution changes dynamically based on the size of the focused region. This keeps national views readable while providing more detail when drilling into smaller areas.

Cloudflare Workers introduced strict memory constraints as the archive grew. Raw observations are stored losslessly in R2, while a Durable Object serializes ingestion so scheduled updates cannot overlap. SQLite handles deduplication and interval generation, and compact derived artifacts are built separately for the interactive parts of the application.

The historical timeline was another major technical challenge. The first version sent thousands of complete records to the browser and repeatedly filtered them as the selected time changed. Its 5,000-record limit eventually covered only around seven days.

The current version merges repeated observations into continuous alert intervals and generates one compact 31-day columnar artifact using shared string dictionaries and parallel numeric columns. The browser builds a small interval index once, allowing playback, scrubbing, and range selection without contacting a Worker during interaction. Updates are limited to one per animation frame, and full source details are fetched only when an alert is opened.

This keeps the original evidence available for inspection while giving each visualization only the processed data it needs.

Strategic goals

  1. 01

    Combine multiple public sources

    Normalize alerts from independent providers while keeping their original source, timing, location, status, and geographic precision visible.

  2. 02

    Visualize overlapping regional data

    Turn differently sized and often overlapping alert regions into comparable 2D and 3D activity maps without double-counting broader and more precise reports.

The challenge

The system had to normalize and deduplicate inconsistent source data, build a cohesive heatmap from overlapping precision levels, and process a growing historical archive within the memory limits of Cloudflare Workers.

Resolution

I derived stable content fingerprints, separated raw observations from compact derived datasets, converted regions into mergeable grid samples, and moved expensive historical and spatial processing into preprocessing and local browser indexes.

Night Watch Ukraine live alert map with both side panels closed and Ukraine filling the view
Night Watch Ukraine showing the 31-day alert timeline

A typical 31-day artifact represents roughly 18,000 alert intervals, while map and timeline interaction stay entirely local.

Scale

Night Watch Ukraine showing the duration-weighted 3D activity map