hellobuilder

Command Palette

Search for a command to run...

← Back to blog

Your Analytics Are Missing Signups: 3 Tracking Traps to Check

Most founders read every funnel off an undercount. The three analytics traps Nikita Bier sees daily, the fixes we shipped, and a one-hour audit.

Nishant Modi
October 13, 2026 · 7 min read
Featured image: Your Analytics Are Missing Signups: 3 Tracking Traps to Check

In February 2025, Nikita Bier, who built tbh and Gas and later ran product at X, posted three traps he keeps finding when founders show him their numbers. An onboarding "problem" that was really triggered by the team's own debugging sessions. Onboarding that looks fine because logged-out users aren't tracked. And sharing that looks healthy because the app tracks attempts, "not the final send events."

We ran that list against Careerkit, a resume and career tool, this week. All three were there. The worst one was simple: over 30 days our analytics recorded 948 signups. The database recorded 2,085 real ones. Every funnel we had looked at in months described 45% of the people who actually signed up.

This post is the practical version. Below: the one comparison that exposes the problem, each of the three traps with how it hides and how we fixed it, the attribution gap that sits behind them, and a one-hour audit you can run on your own product today.

The two numbers that should match, and usually don't

Every product has two signup counts. One lives in your analytics tool: PostHog, Google Analytics, Mixpanel, whatever fires the "signed up" event. The other lives in your auth database, where an account either exists or it doesn't. The database is the truth. The analytics count is a sample of it, and you have no idea how good a sample until you put the two side by side.

Do it for the same 30-day window. Exclude test accounts and, if your auth provider supports them, anonymous or guest users. On Careerkit, 3,370 accounts were created in 30 days, but 1,285 of them (38%) were anonymous sessions that never became real signups. Counting those would have made the gap look smaller than it was.

A small gap is normal. Ad blockers and consent banners drop some events, and some browsers kill the page before an event is sent. A gap of more than about 10% is not noise. It means some path into your product never fires the event at all, and that path is almost never random. It is usually your best users.

Trap 1: your own sessions are in production analytics

Nikita's first trap is the funnel that looks broken because the people walking through it are you. You test the signup form ten times on a Tuesday, abandon it nine times, and on Wednesday your onboarding conversion has collapsed.

On Careerkit the cause was mundane. The PostHog project key sat in an environment file that every build mode loads, so local development sessions sent events to the production project. Over 30 days, 8,376 events came from localhost. Another 57 came from preview deployments. None of them were users.

The fix

  • Gate the analytics initialisation on the hostname, not on the build mode. Before the analytics client starts, check whether the page is running on localhost, 127.0.0.1 or a preview domain, and skip initialisation if it is. A hostname check also catches local production builds, which a NODE_ENV check misses.
  • Keep real proxies. Careerkit also saw 1,542 events from Google Translate's proxy domain. Those are real people reading a translated page, so they stay in.
  • Filter by host in every query you already have. Fixing the code stops new pollution. It does not clean the history, so any chart that spans the fix date needs a host filter on your production domain.

Trap 2: signups you never see

Nikita's second trap is onboarding that "is working" only because the users who fail it are invisible. The classic version is logged-out traffic that is never tracked. Careerkit passed that check: its free tools are tracked logged-out, 28,182 pageviews in 30 days. It failed a quieter version of the same trap.

The "signed up" event was emitted from three places in the code: the password form, the magic-link flow and the one-time-code flow. Google sign-in went through none of them. A user clicks "Continue with Google", leaves for Google, comes back with a session, and the app never says "new user" to the analytics tool. Those one-click signups were missing from every funnel.

That is not a random 55%. People who sign up with one click are plausibly the most motivated people you have. Any conversion rate measured from "signed up" onward was being computed on the users who had to type a password, and any channel that skews toward one-click users looked worse than it was.

The fix

  1. When a session appears after an OAuth redirect, check the auth provider on the user record. Email and phone providers already fire the event in their own flows, so skip those.
  2. Decide whether this is a first sign-in. On a brand-new account, the created-at and last-sign-in timestamps are a few seconds apart. Every later sign-in moves the second one. We treat anything within five minutes as new.
  3. Store a one-time flag in local storage keyed by the user id, so a refresh cannot fire the event twice.
  4. Wait a moment before firing. The OAuth return is a fresh page load and analytics clients start asynchronously, so an event sent immediately can race the initialisation and vanish. We wait about a second and a half.

Then annotate the day you ship it. Your signup chart is about to roughly double overnight. That is not growth, and the next person who reads the chart, including you in three months, needs to know why.

Trap 3: shares that never happened

The third trap is counting the intention instead of the outcome. A share button that fires an event on click tells you someone pressed it. It does not tell you a link left the building.

Careerkit's career test ends on a shareable result card. The "copy link" event fired before the browser had actually written to the clipboard, so a blocked clipboard still counted as a share. Network share buttons have a different limit: when you send someone to X or LinkedIn's share page, you cannot see whether they posted. The honest move is to say so in the data.

The fix

  • Fire the copy event only after the clipboard write succeeds.
  • Label every share event as intent or final. A copied link or a downloaded image is final. A click through to a social network's share page is intent, and the most you can honestly claim.
  • Tag every shared link, for example with utm_medium=share and the network as the source. Then a signup that arrives through a share is credited to it, which is the only share metric that matters.

With the counting fixed, the result card looks small but real: in five days, the 261 people who started the test shared it 15 times. That happens every session, not once on launch day, which is the difference Nikita draws between product-led growth and what he calls "Spotify Wrapped syndrome."

The attribution gap behind the gap

Once events are honest, the next question is where signups come from, and here the referrer data has its own blind spot. On Careerkit, 16.6% of tracked signups arrived as "direct or unknown". The self-reported answer to "where did you hear about us" told a different story: about 21% of new profiles named LinkedIn, X or a friend, channels that show up as almost nothing in the referrer data. Links opened from apps and messages arrive without a referrer, so they look like direct traffic.

Ahrefs found the same thing with AI search. After adding ChatGPT and Claude to the "how did you hear about us?" dropdown in their signup flow, 21.7% of new signups picked one of them. That put AI second only to Google and ahead of YouTube, and they wrote that if they had relied on referral traffic alone they would have "badly undersold it."

  • Ask "where did you hear about us?" once, at signup, with a short fixed list and an "other" box. Only 47% of Careerkit's new users answered, which is plenty to see the shape.
  • Tag every link you own: newsletter, social posts, community replies, emails, your browser extension. Untagged owned links are the biggest source of "direct" traffic you created yourself.
  • Reconcile the two views every quarter. Referrers tell you what can be measured. Self-report tells you what actually happened.

Why these traps survive for months

Each trap produces a number that looks reasonable. A 4% onboarding rate is disappointing, not alarming. A share count that is a little too high feels like good news. Nobody audits a dashboard that is not on fire, so the bug outlives the person who wrote it.

They also arrive after launch, not at it. Analytics usually gets wired up once, around the first signup form. Google sign-in, a magic link, a new share button and a browser extension get added later, often by a coding agent that has no reason to know an event was expected. Every new path into the product is a chance to skip the event, and nothing fails when it does.

The habit that catches this is cheap. On Careerkit, every user-facing change now names one metric that must stay flat after it ships, written into the commit as a single "Guardrail:" line. A new sign-in method names the signup count. A new share button names the share rate. A week later someone checks. If the number moved for no reason, something in the tracking broke, and you find out in days instead of months.

A one-hour audit you can run today

  1. Compare 30 days of signups in your analytics with 30 days of real accounts in your database. Write down the ratio.
  2. Break your analytics events down by hostname. Anything that is not your production domain or a real proxy is pollution.
  3. Sign up once with every method you offer, email, magic link, Google, GitHub, and watch the live event stream. Note which methods never fire the signup event.
  4. Block clipboard access in your browser and press every share button. If a share still counts, you are counting intent.
  5. Open the last five links you posted anywhere. If they carry no tracking tag, the signups they bring will land as "direct."
  6. Add a "where did you hear about us" question if you don't have one.
  7. Write down the date you ship each fix, and annotate it in your analytics tool.

Then watch people before you redesign anything

Counting honestly is step one. On Out of Office in February 2026, Nikita said the biggest gap he sees is founders not "methodically looking at every part of the funnel," and that "there's crazy places that users drop off that you wouldn't ever anticipate."

Careerkit's turned up right after the counting was fixed. 87% of visitors to its career aptitude test never press start. A second page runs the identical component and only 5.8% start, so the difference is the words and the people searching for them, not the layout. The next step is a dozen session recordings of people who left, before anyone touches the design.

Practical takeaways

  • Your analytics signup count is a sample. Check it against the database before you trust any funnel built on it.
  • Gate analytics on hostname so your own testing never reaches production data.
  • Every sign-in method needs to fire the signup event, OAuth included. The one-click path is usually the one that is missing.
  • Count shares only when something was actually sent, and label the rest as intent.
  • Self-reported attribution catches channels referrers cannot: messaging apps, social apps and AI assistants.
  • Annotate every tracking fix, or next quarter's "growth spike" will be your own bug fix.

Conclusion

None of these traps is exotic, which is why they last. Each one makes your numbers look plausible, and plausible numbers are the ones nobody checks. An hour spent comparing two counts, signing up with every method and pressing your own share buttons will tell you whether the dashboard you make decisions from describes your users or just some of them.

We wrote up what else Nikita's playbook found in Careerkit, including what to charge for when nobody asks to pay, in this week's HelloBuilder newsletter. If you run the audit, tell us how big your gap was.

AI is moving fast. Don't get left behind.

Get the weekly digest for AI builders & vibe coders. Curated tools, resources, and stories. Skip the scroll.

Keep reading