Analytics stack — decision, published
ACQUISITION-ANALYTICS §1 asked us to pick between PostHog (self-hosted), Plausible, or GA4. We picked none of them. We built a first-party k-anonymous event pipeline instead. This page explains the decision publicly; the code is src/analytics/.
What we built instead
src/analytics/events.ts— the event taxonomy from ACQUISITION-ANALYTICS §2, verbatim.src/data/postgres/eventDaily.ts— the aggregate store.CHECK (count >= 25), same discipline asquery_shape_daily. No user_id, no session_id, no IP, no sub-day timestamp, no free text.src/analytics/emit.ts— fire-and-forget writer that never blocks the response and drops silently under any failure. Writes to a raw counter table.src/analytics/promoteEvents.ts— nightly aggregator: cells withcount < 25stay in the raw table as unreadable noise and are never promoted to the queryable table.
Why not PostHog (or Plausible, or GA4)
- Self-hosting is a real cost. Self-hosted PostHog needs a VPS with disk, backups, and updates. We don't need that operational surface to answer the questions the spec actually asks (composed answers per week, watchlist adoption, paywall reach). Our k-anonymous counters answer those questions with a single Postgres table.
- Even self-hosted PostHog sends the URL by default. Turning off autocapture is not the same as never having recorded the pageview. On a YMYL site the URL path itself is health data (CLUSTER-5-MASTER L6). Not emitting the URL is a policy; not having the URL is a schema property.
- The team using this data is us. PostHog's value is a UI a growth team browses. We use SQL against Postgres from the admin console. One less product, one less bill, one less thing to audit for privacy drift.
- Plausible is fine for pageviews but too thin for the event taxonomy. We need
paywall_reachedwith afeaturecategorical,answer_composedwith ahadSafetyGate,watchlist_item_addedwithsubjectType. A cookieless pageview counter can't model those without adding a proper events layer — which is exactly what we built. - GA4 is illegal on our surfaces. (CLUSTER-5-MASTER L6.) Not up for consideration.
What this means for you
When you visit an evidence page, no third-party analytics script runs. Our own analytics counts your visit only when it's indistinguishable from at least 24 other visits with the same shape that day — otherwise it stays as unreadable noise and is never surfaced. That's not a promise; it's the schema constraint at CHECK (count >= 25).