Realtime ECMWF Temperature Globe
A self-updating 3D planetary heatmap streaming live forecast data end-to-end: from raw GRIB2 bytes on AWS to a bicubic-interpolated WebGL globe.
Embedded live on the home page
Pipeline Architecture
Twice a day, ECMWF publishes its IFS 0.25° global forecast as multi-gigabyte GRIB2 files on a public S3 bucket. This pipeline surgically extracts just the 2-metre temperature field, decodes it on a DigitalOcean VPS, and serves it to the browser as raw binary — no weather API, no middleman.
- Acquisition: Each forecast file ships with a JSON
.indexsidecar listing the byte offset and length of every meteorological parameter. A Bash pipeline greps the2tentry and issues a ranged S3 GET — downloading ~1.7 MB instead of gigabytes per forecast step. - Decode: A custom C program linked against ECMWF's
ecCodeslibrary reads the GRIB message straight from stdin, converts Kelvin to Celsius, and writes a flat little-endian float32 frame: 1440 × 721 = 1,038,240 grid points. - Serve: nginx exposes the frames with CORS enabled, and a cron schedule refreshes all nine forecast steps (0–24h at 3h intervals) after each 00z/12z cycle publishes, alongside a
manifest.jsonrecording the run's init time. - Deliver: A Next.js rewrite proxies
/weather_data/*to the VPS, so the Vercel-hosted frontend fetches same-origin — sidestepping mixed-content blocking and CORS preflights in one move.
Interpolation Mathematics
The server provides forecast frames 3 hours apart, so the client blends the two frames bracketing wall-clock time per gridpoint, re-evaluating every 10 minutes. The globe you see is always interpolated to now:
Spatially, the native 0.25° grid would blur under magnification. When zooming in, the visible window is resampled to a 1920×1080 texture with a Catmull-Rom bicubic spline — a 16-tap separable kernel that passes exactly through every grid node ():
Finally, the day/night terminator is baked into the texture from the solar zenith angle at each gridpoint, with the subsolar latitude following the seasonal declination:
Solar Zenith
Declination
Live Feed
- • Source: ECMWF IFS Open Data, 0.25° global
- • Grid: 1440 × 721 (1,038,240 points)
- • Frame size: 4.15 MB float32 binary
- • Cycles: 00z & 12z daily, 9 steps each
- • Client refresh: temporal re-blend every 10 min
# Locate the 2t field inside the multi-GB GRIB2
JSON_LINE=$(grep '"param": "2t"' temp.index)
OFFSET=$(echo "$JSON_LINE" | jq -r '._offset')
LENGTH=$(echo "$JSON_LINE" | jq -r '._length')
# Download ONLY those bytes and pipe them
# straight into the ecCodes decoder
aws s3api get-object \
--bucket ecmwf-forecasts \
--key "$GRIB_KEY" \
--range "bytes=${OFFSET}-$((OFFSET+LENGTH-1))" \
--no-sign-request \
/dev/stdout | ./grib2bin "$OUT"
Rendering Stack
deck.gl GlobeView drapes the field over a WebGL sphere; the GPU handles all magnification between interpolated texels.
Forecast data: ECMWF IFS Open Data, © ECMWF, licensed under CC BY 4.0.