How the map draws 137,512 cameras as 148 markers
At the world view the map draws 124 numbered bubbles, and the fattest one sits over the eastern United States reading 24k. Behind them are 137,512 live cameras in 155 countries, the count that page carried when I loaded it at 13:30 UTC on 2026-10-21. Twenty-four of the markers on that first screen are single cameras, drawn as pins because nothing else is close enough to join them. So the whole fleet arrives as 148 things on screen, which is why the map opens at all.
I counted those by loading the map in headless Chromium at 1440 by 900 on 2026-10-21 and asking the page how many .leaflet-marker-icon nodes it held. Add the bubble labels up and you get about 137,445, which is the fleet: the labels round above a thousand, so 24k and 4.4k lose a little on the way.
Clustering happens in the browser, not on the server
The map asks for every camera's position once, in one request, and clusters them locally with Supercluster. On 2026-10-21 that file came down in 1,605,561 bytes of brotli, unpacked to 6,793,244 bytes, and took 2,979 ms. The names arrive separately, 1,247,442 bytes on the wire and 4,408,415 unpacked in 651 ms, because you do not need a camera's name until you hover it. Both are marked private, max-age=300, so the copy that gets reused is the one in your own browser.
Everything after that is arithmetic on an array the page already has. Pan, and no request goes out for markers. Zoom, and Supercluster recomputes which points collapse into which bubble at the new zoom level and Leaflet swaps a few hundred DOM nodes.
I clicked the biggest bubble five times in a row to see how far the node count drifts as the tree opens up:
- 24k over North America, clicked: 222 markers, of which 181 are bubbles and 41 are single cameras. The biggest bubble now reads 12k.
- 12k, clicked: 184 markers. Fewer, because zooming into the middle of a continent pushes half the clusters off screen.
- 4.3k, clicked: 297 markers, 268 of them bubbles.
- 1.9k, clicked: 350 markers. That is the highest count I measured anywhere.
- 1.4k, clicked: 319 markers, and the biggest bubble left on screen reads 873.
So the browser is never asked to lay out more than ~350 markers while the 137,512 cameras counted today sit in memory behind them. The number that matters for a map's smoothness is not the size of the dataset, it is how many nodes the layout engine touches on a pan, and clustering keeps that in the hundreds no matter how the fleet grows.
The basemap underneath is ours
The tiles are the Protomaps planet basemap built from OpenStreetMap data, stored as one PMTiles archive and served from our own domain as /tiles/{version}/{z}/{x}/{y}.mvt. Down in the corner of the map it says "© OpenStreetMap © Protomaps", and the version currently inlined in the published bundle is 20260827.
We moved to hosting it after CARTO started requiring an API key, and the interesting part was the failure mode: unkeyed tiles kept answering HTTP 200 with real map data, with API KEY REQUIRED printed into the image. Nothing errored and nothing logged. A watermark simply appeared on every map on the site, which is a good argument for checking what a response contains rather than what status code it carries.
That version in the path is the whole cache strategy. A versioned tile URL cannot change content, so a tile comes back public, max-age=31536000, immutable and the edge can keep it for a year. Refreshing the basemap means uploading a new archive and changing one constant, and the old URLs age out on their own with nothing to purge. The route deliberately does not check the version against the live one, so a page that loaded moments before a refresh keeps drawing instead of hitting 404s mid-session. The older unversioned route still answers, on 30 days and without immutable, and exists only so a browser that was already open across a deploy keeps rendering.
Sizes, measured with curl on 2026-10-21. London at zoom 11 is 189,500 bytes of vector tile, and 131,558 after gzip, so compressing at the cache layer is worth 30.6% on the densest sort of tile we serve. Valemount in British Columbia at the same zoom is 14,497 bytes. McMurdo is 2,540, which is about what an ice shelf costs to draw.
What the edge is actually holding
Four tiles cover the opening world view, 207,817 bytes between them, and all four came back cf-cache-status: HIT. Two of the shallow tiles I checked by hand had been sitting at the edge for a while: Tokyo at zoom 11 reported an age of 209,578 seconds, and the zoom 5 tile over western Europe 3,018,626 seconds, which is 34.9 days of not touching our origin.
Deeper in, the hit rate falls off exactly as you would expect. Each of those five cluster clicks pulled 12 to 15 new tiles, between 0.55 and 0.87 MB. The first two steps were 12 of 12 and 15 of 15 from cache. The third was 14 of 15. By zoom 5 it was 9 of 15, and by zoom 6, somewhere over a corner of Europe nobody had asked for that minute, 4 of 12. Popular shallow tiles live at the edge more or less permanently and the long tail is fetched from R2 on demand, which is the right way round.
The archive stops at zoom 15, which is street level. The tile that holds Charing Cross is 62,279 bytes on the wire and 113,014 once unpacked, and decoding it turns up Whitehall, Craven Street and 10 Downing Street by name, which is the resolution at which a camera's pin lands on the correct side of the road. That is the deepest tile the route serves.
What gets refreshed, and the number I want down
Protomaps puts out a planet build most days and keeps only the past week of them, plus the latest build of each patch version, as its download docs say. The 2026-10-27 build answered a HEAD request from me on 2026-10-28 with a content-length of 139,197,622,108 bytes, against the 2026-08-27 build we are serving. OpenStreetMap moves slowly at the scale a basemap cares about, so that gap costs a reader almost nothing and the archive gets refreshed once or twice a year rather than nightly. The next thing I want down is that 2,979 ms the map spends on the markers file. It is one request, it is cached for the session, and the map is interactive before it lands, but 1.6 MB of coordinates is the single biggest thing a first visit pulls from us, and the fleet is still growing.