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 (1)

Collapse
 
wolf2016 profile image
wolf Valencia •

Polling the Events API with ETags and honoring the poll interval GitHub sends back is the right call. Plenty of "live" GitHub demos burn through rate limits fast. Two small fixes for the demo link, since that's what gets shared:

  1. index.html has no meta description, so search results and some link previews show nothing under the title. A single <meta name="description" content="A live 3D globe of public GitHub activity by city"> line fixes it.
  2. There are no Open Graph or Twitter card tags either, so shares on X, Slack or Discord unfurl as a plain link. og:title, og:description, og:image (a screenshot of the globe works well) plus twitter:card = summary_large_image in the same file sorts it.

Are the 15-minute buckets aggregated server-side, or does the client do that?