02 / Case study / 2026
Penn Analytics
A self-hosted, privacy-first replacement for Google Analytics across roughly 500 university sites.
The problem
Penn’s privacy and audit review reached an uncomfortable conclusion about Google Analytics: at roughly five hundred sites, each running its own account with its own data-sharing settings, the university could not actually say what was being collected or where it went. The contractual protections were inconsistent. Nobody could verify the settings at scale.
The obvious fix — a policy memo telling five hundred site owners to configure GA correctly — is not a fix. It is a wish. If you want governance, you have to own the pipe.
What it is
Penn Analytics is a self-hosted analytics platform built to be swapped in without anyone rewriting their site. One line replaces the tag: a cookieless tracker under three kilobytes that ships a shim, so existing gtag(), ga() and dataLayer.push() calls keep working exactly as they did.
Behind that line is a real reporting product, in GA4’s own vocabulary — realtime, pages, acquisition with default channel grouping, audience, events, key events, funnels, retention, explorations with segments, annotations, share links, scheduled email reports, and CSV or Parquet exports. If the reports do not match what a communications team already knows how to read, they will not switch. So they match.
The engineering
A TypeScript monorepo on pnpm: a Fastify ingest API and worker, ClickHouse for events, PostgreSQL for metadata, Redis for the ingest queue and session state, React 19 and Vite for the dashboard, all deployed with Docker Compose behind Caddy.
ClickHouse was the deliberate choice — multi-year, multi-site reporting is exactly what it is for, and one language across the stack is what a small central team can actually maintain. Documentation is a full Starlight site covering install, migration from GA, report definitions, privacy, governance, the tracker and API reference, hosting, and a runbook.
Governance as a feature
The part that makes it an institutional product rather than a side project: every site lives under its school or centre in one University account tree, with approvals, roles, an inventory export, an append-only audit log, and per-site retention.
No IP address or user-agent string is ever stored. The privacy register is generated from live settings rather than written by hand, which means it cannot quietly drift out of date. Nothing leaves Penn’s infrastructure.
Why it is the interesting one
Most “replace the vendor” projects fail on the migration, not the technology. This one is designed around the migration: keep the calls working, keep the reports familiar, and make the privacy story something a reviewer can verify instead of trust.