Collecting Heatmap Data Without Drowning Your Database
The volume problem
A pageview is one event. A session with heatmaps enabled produces dozens: every click, scroll milestone and rage-click burst. Naive collection turns a manageable event stream into an unmanageable one.
Three decisions keep it affordable.
Normalise coordinates at capture
Raw pixel coordinates are meaningless across devices — x: 840 is the right edge on a phone and the centre on a desktop.
Store a percentage of the viewport instead:
const x = +(event.clientX / window.innerWidth * 100).toFixed(2); const y = +(event.pageY / document.body.scrollHeight * 100).toFixed(2);
Two benefits: one heatmap works across every screen size, and two decimal places is enough precision while keeping the values small.
Scroll depth as milestones, not a stream
Tracking scroll position continuously produces an event per frame. Nobody needs that resolution.
Fire once per milestone — 25%, 50%, 75%, 100% — and only the first time each is reached in a session. A long article produces four events instead of several hundred, and the reports are identical, because "how far down did people get" is a milestone question.
Capture the element, not just the point
A click at 34% across and 71% down tells you where people clicked. It does not tell you what they clicked, which is the actually useful question.
Record a stable selector and the visible text alongside the coordinates. Then "which button gets clicked most" becomes a GROUP BY rather than a visual estimate from a blob.
SELECT text, selector, COUNT(*) AS clicks, COUNT(DISTINCT user_id) AS users FROM events WHERE site_id = ? AND type = 'click' AND path = ? GROUP BY text, selector ORDER BY clicks DESC LIMIT 30;
Sample on high-traffic pages
A page with a million views a month does not need every click to produce an accurate heatmap. Sampling at 10% gives a visually identical result for a tenth of the storage.
Sample by session, not by event — sampling individual events breaks funnel and sequence analysis, because you end up with partial journeys.
Rage clicks are worth isolating
Three or more clicks on the same element within about a second usually means something looks interactive and is not. That is a specific, actionable signal, and it is worth detecting at capture time rather than reconstructing later.
It is often the single most useful thing heatmap data produces.
Try InsightsTrack free
Open-source, self-hosted, privacy-first analytics — explore the live demo, no install required.
Open live dashboard