Features · Analyse
A 3D globe and a 2D map drawn on a canvas from geometry we serve ourselves: sessions placed at their city, a choropleth by country and by state or province, and a timeline you can scrub and play. No map provider, no token, no third party learning which dashboards you open.
Timeline (sessions as avatars at their city, with a scrubber and play button), Coordinates (glowing dots per 0.1° cell), Countries and Subdivisions (states and provinces). Toggle 3D and 2D without losing your place; drag, zoom, fly to a country.
City, subdivision and coordinates come from the headers your proxy already sets — Cloudflare's visitor-location managed transform, Vercel or CloudFront — all from one provider, with coordinates rounded to 0.1 degree for privacy and honest precision.
Every shaded country filters the whole dashboard, and every count on the page opens its query in the same evidence panel as everything else.
With no city headers the page names the missing header and the switch that turns it on, instead of drawing an empty map. Country-only sessions are counted, never pinned to a country's centre.
The evidence
SELECT lat, lon, MAX(city) AS city, MAX(country) AS country,
COUNT(DISTINCT session_id) AS sessions
FROM events
WHERE site_id = ? AND ts >= ? AND ts < ?
AND bot_kind = '' AND agent_trust = 'human'
AND lat IS NOT NULL AND lon IS NOT NULL
GROUP BY lat, lon ORDER BY sessions DESC LIMIT 5000
geo.coverage runs first and reports how many sessions carry a country, a region, a city and coordinates — which is how the page tells "no visitors" apart from "no city headers".
No proxy, no location: we do not bundle a GeoIP database, because a 60+ MB file with a monthly update cycle would break the one-command install. Netlify and Fly send a country but no city. The Timeline places at most the latest 5,000 sessions in the window and says so on screen.