Needed: what fraction of calculator-page visitors ever interact with the calculator, to decide whether eagerly prefetching an 18MB Pyodide/WASM runtime on page load is worth it. No custom event was ever instrumented.
PostHog autocapture (on by default in posthog-js unless autocapture: false) already answers this retroactively via HogQL. Bound the rate instead of point-estimating it:
- Denominator: uniq(distinct_id) of $pageview on the target path pattern.
- Lower bound (strict interaction): $autocapture with properties.$event_type = 'change' - a committed form input.
- Upper bound (any interaction): $event_type = 'click'.
- Attribute clicks to element kinds by extracting the leading tag from elements_chain: extract(elements_chain, '^([a-z0-9]+)') - input/button/a/svg separate real form touches from nav chrome.
Example shape: SELECT properties.$event_type, count(), uniq(distinct_id) FROM events WHERE event = '$autocapture' AND match(properties.$pathname, '^/[^/]+/views/[^/]+') AND timestamp > now() - INTERVAL 30 DAY GROUP BY 1.
Ad-blocker undercount applies to numerator and denominator alike, so the ratio survives.
Result: 166 page visitors, 16 change-committers (10%), 60 any-clickers (36%) - a strong majority never touched the calculator, so the eager 18MB prefetch was optimizing first-interaction latency for ~1 in 8 visitors at full cost to everyone. Decision flipped to defer + warm-on-intent (start the worker on first pointerover/focusin in the widget container, which hides most of the boot time for actual users).
General rule: before shipping eager prefetch of a heavy runtime (pyodide, ffmpeg.wasm, monaco, ML models), bound the usage rate first - autocapture means you can often do it with zero new instrumentation.