Analytics — 5-tier stack (CFWA + GA4 + PostHog + Clarity + UTM)
Analytics — 5-tier stack (CFWA + GA4 + PostHog + Clarity + UTM)
Decision
Every site in the family runs five analytics layers in parallel,
each covering a different question with no overlap. All five are
free, no card, and each can be killed by a per-site
ENABLE_<TOOL>=true|false env-var without affecting the others.
| # | Layer | Service | Question it answers |
|---|---|---|---|
| 1 | Edge / raw load | Cloudflare Web Analytics | How many real visitors, from where, on what URL? (cookieless) |
| 2 | Marketing funnel | Google Analytics 4 (GA4) | Acquisition / engagement / conversion against the same definitions advertisers use |
| 3 | Product analytics | PostHog | Funnels, retention, feature-flag usage, session replay (product side) |
| 4 | Heatmaps + session replay (vendor-redundant) | Microsoft Clarity | Where do users click / scroll / rage-click; second replay so a PostHog quota miss never blinds us |
| 5 | Attribution convention | UTM tracking | Which channel / campaign drove this session — read by tiers 2-4 from the URL |
Why five and not fewer
The user's direction was: "I want to use all of the analytics and all of the Google practices, Microsoft Clarity and everything … I want a free service for everything." Picking only one layer leaves real questions unanswered:
- CFWA alone = no funnels, no replay, no heatmaps.
- GA4 alone = privacy-hostile, no replay, sampled at scale.
- PostHog alone = single-vendor risk; 1M-events/mo cap blinds the family the moment a post goes viral.
- Clarity alone = no funnels, no flags, no acquisition reports.
- UTM alone = a convention, not a tool — needs a tool to read it.
The five layers together answer every operationally interesting question with vendor redundancy on session replay (PostHog + Clarity) and funnel redundancy (GA4 + PostHog). Each layer preserves the family's no-card-on-file rule and each runs at a different vendor, so a single outage / quota trip never goes dark across the board.
Quota safeguards (per rules/interaction/never-hit-quotas.md)
Each layer has a per-site env-var kill-switch:
ENABLE_CFWA=true # Cloudflare Web Analytics (no real cap)
ENABLE_GA4=true # GA4 — sampled past 10M events/mo (free)
ENABLE_POSTHOG=true # PostHog — 1M events/mo, 5K replays/mo
ENABLE_CLARITY=true # Microsoft Clarity — no documented cap
ENABLE_UTM_HELPER=true # <UtmLink> validation in @chirag127/oriz-kit
Set any to false per site if a quota cliff approaches. The
<Analytics /> component in
reads these flags at build time and tree-shakes the unused scripts.
Implications
- One
<Analytics />component inoriz-kitinjects all five scripts based on the env-vars; sites do not hand-wire vendor SDKs. - PostHog is the primary for session replay (fed flags + PostHog Insights); Clarity is the redundant second so a PostHog quota trip / outage doesn't blind us to user behaviour.
- GA4 is configured to read UTMs as the standard
utm_source/utm_medium/utm_campaigndimensions; PostHog + CFWA do the same perutm-attribution-strategy.md. - CSP allow-list in
_headerspreset covers all five vendor origins (cloudflareinsights, googletagmanager, posthog, clarity.ms). No per-site CSP exception. - Cookie banner (
Klaroalready locked) gates GA4 + Clarity + PostHog behind explicit consent in regions that need it; CFWA is cookieless and runs without consent. UTM capture is read-only off the URL — no cookie required. - No paid tier ever. If any layer hits its quota:
- Toggle the env-var off on the highest-traffic site.
- Document in which site / which layer.
- Consider sampling (
ENABLE_<TOOL>=trueonly on 10% of sites) before turning back on.