30M
events a day from the biggest site
The median site sends about a hundred. Five to six orders of magnitude apart, and both want a 30-day dashboard in under a second.
The visitor is leaving. When do you send?
Bad: In the unload handler
Delays the next page, and on phones often never runs.
Good: When the page goes hidden
sendBeacon queues a small POST; navigation never waits.
No cookies. So how do you know it’s the same visitor?
Hash IP, user agent and site with a secret salt that changes at midnight, then drop the IP. Old salts die after 48 hours.
Unique visitors: 100 at nine, 120 at ten, 90 at eleven. That’s 310, yet only 200 people came.
The trick
Distinct counts don’t add, but HyperLogLog sketches merge: store one per hour, merge any range, ±0.8%.
900M
rows in the biggest site’s 30 days
Sorted by site, a small site’s month is a few thousand neighbouring rows. For the biggest, daily rollups of counts and sketches answer from 30 rows.
Election night: 30,000 events a second land on one Redis key
It pins one Redis thread and slows the neighbours. Workers instead keep local sketches and flush once a second: 64 writes, not 30,000.
Keep one giant site from hurting others
- Key Kafka by site and visitor
- Split giant sites over 4–8 shards, by visitor
- Past per-site query limits, answer from a labelled sample
- Cache closed days; query only today
Remember
Beacon, hash with a daily salt, append to Kafka. Sort by site, merge sketches from rollups, and spread the biggest sites by visitor.