shouldivibecodeit

Should I vibe codeUsermaven?

Privacy-friendly product analytics, funnels, attribution, and session insights

Fathom counts pageviews. This one knows who Sarah is, where she works and everything she clicked since March.

?

Their verdict, the Growth price and the build-time estimate come from their entry, MIT-licensed. Checked 2026-08-04.

Can you build it?asked by canivibecodeit.com ↗KINDAweekend project · weekend to multi-day
?

Our verdict, the regret score and everything below it. Editorial and unsponsored — nobody can pay to be moved.

Should you ship it?asked by usYOUR FUNERALit’ll work. then it’ll get you.

The honest answer

why the verdict is what it is

We rate Fathom and Pirsch as SHIP IT, and this is the entry where that stops being transferable, so it is worth being precise about why. Privacy analytics counts events. Usermaven joins them to a person: an identify call with an email, a name, a company, a plan, then a full behavioural history hung off that key, a 365-day attribution lookback, revenue pulled in from your CRM, and server-side collection specifically marketed as recovering what ad blockers would have dropped. That join is the whole product and it is also the whole risk. The moment your event table has a user_id and an email in it, you are not running analytics — you are running a surveillance database about your own customers, on a box you set up on a Sunday, with no retention policy, no deletion path and no answer to the first person who writes in asking what you hold about them. The counting is genuinely a weekend. Funnels over a raw event stream are a real engineering problem and get slower every month. But the thing that makes this YOUR FUNERAL is not the query planner, it is that the data is about named human beings who never agreed to be in your side project.

What actually breaks

not "if". the specific failures.

  • Deletion. Somebody exercises their right to erasure and you discover the identifier is denormalised into raw events, daily rollups, funnel caches, an attribution table and a nightly CSV in object storage
  • The funnel query, which is fine at ten thousand events and takes ninety seconds at fifty million, because a funnel is a self-join over an ordered stream and nobody's first implementation survives contact with a year of data
  • Auto-capture, which is sold as no-code and which happily records the text of every button — including the ones containing customer names, order totals and email addresses
  • URLs, which carry password reset tokens, invite codes, search terms and sometimes an email in a query parameter, and which get stored verbatim by default
  • Server-side collection, the ad-blocker workaround, which quietly relocates a consent question into your own first-party domain where nobody is looking at it
  • Attribution itself, which is a model rather than a measurement — change the lookback window or the channel grouping and last quarter retroactively disagrees with itself
  • The history, which is the only reason the product has value and cannot be backfilled after a migration you decided not to write
and then, at 3am

The email arrives on a Thursday and is polite. A customer wants a copy of everything you hold about them and then wants it deleted, and cites the article number. You know where the users table is. Then you remember the raw events table keyed on user_id, and the daily rollups that denormalised the email in so the dashboard would not need a join, and the funnel cache, and the attribution table that keeps a 365-day trail of touchpoints, and the nightly CSV dump in object storage that exists because you once needed to debug something and never turned it off. It takes until Sunday to write the query that finds all of it, and most of that time is spent discovering places you had forgotten the identifier travelled to. The deletion itself takes four seconds. What is genuinely uncomfortable is realising that you have no idea whether the answer you sent was complete.

Is that you?

the verdict is a default, not a law

ship it if
  • The events are anonymous and stay anonymous — no user id, no email, no stable cross-session identifier
  • It is your own site's traffic and the numbers are for you
  • Raw events have a short retention and everything durable is a pre-aggregated rollup
  • You have restored the rollup table from a backup at least once
don’t ship it if
  • Events are joined to named users and there is no tested path to find and delete one person
  • Auto-capture is on and nobody has looked at what the captured labels actually contain
  • You are collecting on behalf of other companies' products as well as your own
  • The consent story is 'it's first-party so it's fine'
  • There is one database, no retention policy, and the word 'forever' appears anywhere in the design

If you build it anyway

the checklist, then the prompt that enforces it

  1. Decide on day one whether events are identified. If they are not, this is a much smaller and much safer project and you should say so out loud before writing schema.
  2. If they are identified, build erasure before you build a single chart. One function that takes a user id and provably removes them from every store — raw, rollup, cache, export — and a test that proves it.
  3. Keep the identifier in exactly one place and join to it. Denormalising an email into the rollup for query speed is how deletion becomes impossible.
  4. Separate raw events from aggregates and put a hard retention on the raw side. The aggregates are what you keep; the raw stream is what gets you sued.
  5. Strip query strings from stored URLs or allowlist parameters explicitly. Reset tokens and email addresses live in URLs and you will store them by accident.
  6. Review what auto-capture actually captures on your own app before enabling it anywhere else. Button text is user content.
  7. Write the consent decision down and implement it. Server-side, first-party collection changes where the request goes, not whether you needed a lawful basis for it.
  8. Version the funnel and attribution definitions, and stamp every stored result with the version. A methodology change that looks like a traffic change will cost somebody a quarter.
  9. Back up the aggregate tables and restore one into a scratch database before you trust any of this. Analytics history cannot be recreated.
the guardrail prompt
I am building identified product analytics — events joined to named users, plus
funnels and attribution. Treat the identity join as the dangerous part and
apply these in order. Argue with me if I want to reorder them.

1. Before schema, ask whether events really need to be identified. If I only
   need counts, tell me so and build the anonymous version instead — it is a
   different and far safer product.
2. If identity stays, the first feature is erasure, not dashboards. One
   function, user id in, provable removal from every store, with a test.
3. Enumerate every place an identifier can end up — raw events, rollups,
   caches, funnel results, attribution trails, exports, logs — and keep that
   list in the README. Erasure covers all of them or it covers nothing.
4. Store the identifier once and join. Refuse to denormalise an email into an
   aggregate table for query speed, and say why when I ask for it.
5. Split raw events from aggregates immediately. Raw gets a hard retention
   window; aggregates are what survives.
6. Strip query strings from stored URLs unless a parameter is explicitly
   allowlisted. Assume reset tokens and email addresses are in them.
7. If I ask for auto-capture, show me a sample of what it records on my own
   app first, including button and form label text, before it is enabled.
8. Do not implement ad-blocker circumvention as a default. If I want
   first-party server-side collection, state plainly that it changes the
   network path and not the consent question.
9. Funnel and attribution definitions are versioned, and every stored result
   carries its version, so a methodology change is visible as one.
10. Design the funnel query against a synthetic fifty-million-row table before
    it goes near a UI. If it does not hold up, say so rather than shipping
    something that is fast in the demo.
11. Automate a backup of the aggregate tables and write the restore script.
    Tell me to run the restore before I trust the system.
12. Out of scope unless I ask, and say so: session replay, cross-site
    identity, and anything that outlives the retention window. If I want the
    full product, Usermaven's Growth plan is $84 a month and someone else
    holds the data.
paste this before you build — not after something breaks34 lines · 2229 chars

That one keeps you out of trouble. For the prompt that actually builds it, canivibecodeit.com has one.

their build prompt ↗

Or don’t build it

the boring option, and the way back out

just pay for it

As soon as the event stream carries other people's names. $84 a month for Growth buys 250k events, five years of retained history and — the part that matters — a company whose job includes answering a data subject access request, keeping the funnel query fast as the table grows, and not losing five years of history to a schema change. That is a lot of specialised, unglamorous work to take on so that you can own a dashboard. If all you actually wanted was traffic counts, look at the SHIP IT entries in this category instead; they are cheaper and they are a genuinely different risk.

$84/mo is cheaper than your weekend.

your exit plan, if you already built it

There are two assets and they need opposite treatment. The aggregates — daily counts by event, path, channel and cohort — are small, portable and the only reason the tool has value after year one, so keep them exportable as CSV and back them up somewhere your app cannot reach. The identified raw stream is a liability with a shelf life, so it should be expiring continuously rather than waiting for you to decide what to do with it. If you shut the project down, the correct final act is deleting the raw events, and if you cannot do that confidently in one command, that is the real finding of this exercise.

prior art · someone already did this
PostHog

Open-source product analytics with funnels, feature flags and session replay, and the only realistic self-hosted starting point for the identified version.

Matomo

Long-running self-hosted web analytics with the consent and data-retention machinery already built.

Questions

You rate Fathom and Pirsch SHIP IT. Why is this two bands away?

Because they are not the same product wearing different logos. Fathom and Pirsch count events with no stable identifier — worst case you lose a graph. Usermaven's core feature is joining events to a named person and following them for a year. Once you build that, a leak is a disclosure notice about your own customers and a deletion request is an archaeology project. The dashboards look similar; the thing in the database is not.

If I skip the identify call, is it SHIP IT?

Effectively, yes, and that is the most useful thing on this page. Strip the user id, drop the cross-session identifier, keep daily rollups, and you have built the Fathom-shaped thing we already recommend building. You lose funnels-by-person and attribution, which is a real loss — but it is a product decision with a known price, rather than a liability you acquire without noticing.

Everyone says self-hosted analytics is more private. Is that wrong?

It is right about where the data sits and wrong about what follows. Self-hosting means no third party has a copy, which is genuinely better. It also means you are now the data controller and the processor, so retention, erasure, access requests, encryption at rest and breach notification are yours. That is a fine trade if you do the work. It is a much worse position than the SaaS if you assumed privacy came from the hostname.

Where does the funnel query actually fall over?

Around the point where the raw table stops fitting in memory. A funnel is an ordered self-join over per-user event sequences, and the naive version — which is what gets generated first — degrades non-linearly. It will be instant in the demo, fine for three months, and then somebody adds a fourth step and it takes ninety seconds. The fix is a columnar store and a different query shape, which is a rewrite, not a tuning session.

sources
  • GDPR Art. 5 — principles relating to processing of personal data (EU)
  • GDPR Art. 17 — right to erasure, the request this design has to survive (EU)
  • GDPR Art. 32 — security of processing (EU)
did you build it?

Every week, someone ships something they shouldn’t have.

New verdicts, the worst thing that landed in the trap, and the occasional incident report. No other email, ever.

also on the regret index
Fathom AnalyticsSHIP IT

The dashboard is a weekend. The five-year graph is the product, and you get it only by never losing the table.

Piwik PROYOUR FUNERAL

A tag manager is a supported way to run arbitrary JavaScript on every page. You are building the auth for that.

GoSquaredDEMO ONLY

Aggregates are numbers. A live visitor feed is a list of people, and you just put it on the office TV.

last reviewed 2026-08-05 · verdict is editorial and unsponsored · shared entry data from canivibecodeit under MIT · not legal advice