SELF-HOSTED ANALYTICS TOOLKIT
30 minutes to deploy. 16 years to design.
Clone the repo. Set up Supabase. Deploy the dashboard. You're tracking in 30 minutes.
Measr isn't a weekend project. It's the distillation of every analytics implementation mistake I've seen, and the standard I built to stop making them.
Built by
Digital analytics consultant with 16 years in the field. I've built analytics departments from scratch at Metro AG, designed tracking strategies for Zürcher Kantonalbank's entire digital ecosystem, and led Mazda Europe's GA4 migration. Every project, same story: tracking that's either too simple (pageview counters) or too complex (GA4 with 47 custom dimensions nobody understands). So I built the CDE Analytics Standard, a 19-module event taxonomy that covers everything a marketing site or web app actually needs. Measr is that standard, packaged as a product.
Enterprise experience: Mazda Motors Europe, Metro AG, Zürcher Kantonalbank, Peek & Cloppenburg, Commerzbank, 20+ e-commerce brands via econda
Connect on LinkedInNo build tools. No complex configuration. No vendor lock-in.
Every click fires a real event to Supabase. Enter your name, interact with the page, then find your session in the dashboard.
Your session appears in the dashboard within seconds.
Each module tracks a specific type of user behavior with a defined event schema. No guesswork. No "custom events with 14 parameters."
19 modules are defined in the CDE Analytics Standard. 9 ship today. The remaining 10 are specified and ready. They ship as demand validates them.
Self-hosted depth with none of the setup pain.
| Feature | Measr | Umami | Plausible | PostHog | OpenPanel | GA4 |
|---|---|---|---|---|---|---|
| Self-hosted | ✓ | ✓ | ✓ (CE free) | ✓ | ✓ | ✕ |
| You own the data | ✓ | ✓ | Depends | Depends | ✓ | ✕ |
| Pre-built event taxonomy | ✓ (9 modules) | ✕ | ✕ | ✕ | ✕ | ✕ |
| Interaction tracking | ✓ Auto | Manual | ✕ | ✓ Auto | ✕ | Manual |
| Video tracking | ✓ | ✕ | ✕ | ✓ | ✕ | Manual |
| Download tracking | ✓ Auto | Manual | ✕ | ✓ | ✕ | Manual |
| Form tracking | ✓ Auto | ✕ | ✕ | ✓ | ✕ | Manual |
| Scroll depth | ✓ Auto | Plugin | ✓ | ✓ | ✕ | Manual |
| Dashboard included | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| Unlimited events | ✓ | ✓ | Tiers | Tiers | ✓ | ✓ |
| No cookies | ✓ | ✓ | ✓ | ✕ | ✓ | ✕ |
| Supabase-native | ✓ | ✕ | ✕ | ✕ | ✕ | ✕ |
| GDPR deletion | ✓ (via SQL) | Manual | ✓ | ✓ | ✓ | Complex |
| Setup time | ~30 min | ~15 min | ~5 min (hosted) | ~30 min | ~10 min | ~15 min |
| Monthly cost | €19 | Free | €9-99+ | Free-$$$ | Free-$2.50+ | Free |
No tag managers. No data layers. No configuration files. Call init(), everything fires.
Use Claude Code? The setup and update skills handle everything.
What you get that Umami, Plausible, and PostHog don't ship.
No tiers. No feature gates. No per-seat charges. Everything, always.
Or pay €190/year and save 2 months →
Three steps from checkout to your first tracked event.
excludeBots: false if you want to analyze bot traffic.analytics_events, analytics_sessions, analytics_video_events) and RPC functions to your project. They don’t conflict with your existing schema. The migration scripts are additive — they create new objects, they don’t alter existing ones.site column. One Supabase project can track multiple sites or apps. The dashboard includes a site switcher. Just set a different siteId in each site's Measr configuration.git pull.Every field, every module, fully transparent. No hidden data collection. No mystery payloads. This is the complete schema your SDK sends to your Supabase.
| Field | Type | Description |
|---|---|---|
| session_id | uuid | Auto-generated per browser session |
| anonymous_id | uuid | Persistent visitor ID (localStorage) |
| site | string | Your site identifier |
| page_name | string | Current page at time of event |
| device_category | string | Desktop or Mobile |
| geo_language | string | Browser language (e.g. en-US) |
| geo_region | string | Timezone-based region |
| created_at | timestamp | Event timestamp (ISO 8601) |
| Field | Type | Description |
|---|---|---|
| pageName | string | Name of the current page |
| previousPageName | string | Previous page (or "Entry") |
| originalReferrer | string|null | First page view only |
| queryParameters | string|null | URL query string, first page view only |
| Field | Type | Description |
|---|---|---|
| interaction.element | string | What was clicked (e.g. "CTA button") |
| interaction.name | string | Action name (e.g. "signup_click") |
| interaction.click_count | 1 | Always 1 per event |
| Field | Type | Description |
|---|---|---|
| navigation.type | string | Nav category (main, footer, sidebar) |
| navigation.value | string | Target page or link label |
| navigation.click_count | 1 | Always 1 per event |
| Field | Type | Description |
|---|---|---|
| exit_link.url | string | Full outbound URL |
| exit_link.click_count | 1 | Always 1 per event |
| Field | Type | Description |
|---|---|---|
| scroll.depth | string | Milestone: 25%, 50%, 75%, or 100% |
| scroll.hit_count | 1 | Always 1 per milestone |
| Field | Type | Description |
|---|---|---|
| video.name | string | Video identifier |
| video.milestone | string | 0%, 25%, 50%, 75%, 90%, 100% |
| video.seconds | number | Seconds since previous milestone (delta) |
| video.start_count | 0|1 | 1 only at 0% milestone |
| video.90percent_count | 0|1 | 1 only at 90% milestone |
| video.hit_count | 1 | Always 1 per milestone |
| Field | Type | Description |
|---|---|---|
| error.message | string | Error message text |
| error.count | 1 | Always 1 per error |
| Field | Type | Description |
|---|---|---|
| download.name | string | File name |
| download.type | string | File extension (pdf, csv, etc.) |
| download.count | 1 | Always 1 per download |
| Field | Type | Description |
|---|---|---|
| form.name | string | Form identifier |
| form.view_count | 1 | Sent with form_view |
| form.start_count | 1 | Sent with form_start |
| form.end_count | 1 | Sent with form_end |
19 modules are defined in the CDE Analytics Standard. 9 ship today. The remaining 10 are specified and ready. They ship as demand validates them.
Stop renting dashboards. Stop feeding your data to someone else's servers.