DEV Community

Cover image for GitPulse – a live 3D globe of GitHub activity
ADITYA VYAS
ADITYA VYAS

Posted on

GitPulse – a live 3D globe of GitHub activity

I kept wondering what GitHub would look like if you could see it instead of reading it. So I built Git Pulse: a live 3D globe of public GitHub activity, by city.

Live demo: https://gitpulse3d.vercel.app

You can search a city and fly there, filter by language or activity type, and replay the last 24 hours. The day/night line follows the real sun.

How it works

GitHub Events API → validate → dedupe → resolve a location → aggregate into 15-minute buckets → Postgres + Redis → REST and WebSocket → React Three Fiber.

Surprise #1: most developers don't list a location

I collected 1,000 real events and checked the profiles behind them. Only about 23% of the sampled profiles had a location at all, and fewer still matched a city I could place. That's why the app uses a fixed catalog of 70 cities, and why it shows a subset of the world, not all of it.

Surprise #2: "live" isn't real-time

The Events API is polled, not streamed. I use conditional requests (ETag), follow the poll interval GitHub sends back, and retry with backoff. "Live" here means continuously updated.

Drawing it without melting the GPU

All markers are one InstancedMesh of 500 pooled slots, drawn in a single call. Detail changes with camera distance (80, 240 or 500 markers), so zooming out stays smooth.

The day/night effect comes from real astronomy: the sun's position is computed from the date, and the replay moves it to the selected time.

The bugs that only showed up in production

A server that kept falling asleep. On Render's free tier the backend slept when idle, so visitors saw an empty globe. A cron job now pings /health every 10 minutes.

Hover tooltips that worked locally and died in production. three.js builds an InstancedMesh's bounding sphere on the first raycast and never rebuilds it. Locally my data arrived instantly. In production the API sometimes answered after my first mouse move, so an empty sphere got cached and every later hover missed. The fix was a fixed sphere that always encloses the globe:

mesh.boundingSphere = new Sphere(new Vector3(0, 0, 0), 1.25);
Enter fullscreen mode Exit fullscreen mode

Privacy

Git Pulse shows where, never who: city-level activity only, no usernames, no repositories.

Try it

https://gitpulse3d.vercel.app

I'd love feedback, especially on the location matching. Where is your code being built?

Top comments (0)