Attribution · Sprites diagnoses this

PostHog vs Google Ads: why your signups don't match

Google Ads counts conversions from its own tag, on the click date, across devices and with modeled conversions for opted-out users. PostHog counts the events it captures and credits them to the UTMs it stored on the person or session. Ad blockers, lost UTMs and a different definition of a signup make up most of the gap.

$1 today. Cancel anytime before day 7.

What Sprites checks

  • ✓Signup event in PostHoguser_signed_up, fired 30 days
  • !Paid signups by utm_source41% with no UTM at all
  • ?Google Ads conversion actionCounts form submit, not signup
  • ✓Internal users filteredFilter on
Illustration of a typical broken account. Your own readout comes from your account.

Why it happens

Two different events

  1. Two different events

    The Google Ads tag usually fires on a form submit or thank-you page. PostHog counts the signup event your app sends once the account exists. Abandoned or failed signups count on one side only.

  2. UTMs lost before PostHog sees them

    A redirect, a separate app domain or an auth flow that drops the query string leaves the person without utm_source. PostHog then files them as direct. See PostHog UTM tracking.

  3. Ad blockers

    Many blockers stop analytics scripts that load from a third-party host. Without a reverse proxy, PostHog misses a slice of visitors that Google Ads still counts.

  4. Dates and modeling

    Google Ads reports on the click date and adds modeled conversions for users who declined cookies. PostHog reports on the event date and models nothing.

How to line them up, step by step

  1. Agree on one event

    In Google Ads open Goals, Conversions, Summary and check which page or event the primary action fires on. Compare it with the PostHog event you treat as a signup.

  2. Break PostHog signups down by source

    In PostHog create a Trends insight on the signup event and break it down by the person property Initial UTM source, then by Initial UTM campaign.

  3. Check the share with no UTM

    If a large share of signups shows no initial UTM source, the parameters are getting lost between the ad and the app. Test the ad URL end to end in a private window.

  4. Compare on conversion time

    In Google Ads add Conv. (by conv. time) and compare the same 30 days with the PostHog trend.

Steps checked against PostHog docs: Capturing UTM and campaign data; PostHog docs: Deploying a reverse proxy; Google Ads Help: About the Conversions (by conv. time) column.

Sprites diagnoses this

Sprites diagnoses it

Sprites lines up your PostHog signups and Google Ads conversions and shows where they split.

What Sprites does

  • Reads what your PostHog project actually tracks, so it compares the real signup event, not a guessed name.
  • Breaks PostHog signups down by utm_source, utm_medium and utm_campaign, including the share with no UTM at all.
  • Pulls Google Ads conversions per campaign and per conversion action for the same dates.

What it doesn't do

  • It does not send PostHog events back to Google Ads as conversions.
  • It does not edit your PostHog setup or your site.

Questions

Can PostHog send conversions to Google Ads?

Not natively as an offline import. Teams usually send the signup to Google Ads with the gclid through a server-side upload or a CDP. Sprites does not do that upload.

Why does PostHog show fewer paid signups than Google Ads?

Usually lost UTMs, ad blockers and a different event definition. Google Ads also models conversions PostHog never captured.

Which number should I trust?

PostHog for what users did after signup and for activation by source. Google Ads for bidding, because that is the number Smart Bidding learns from.

Does PostHog read the gclid?

PostHog stores the gclid as a campaign property when it is in the landing URL, so you can break signups down by it. See the gclid page for why it goes missing.

See where it breaks

Connect your accounts. Sprites reads them side by side and shows you exactly where the numbers split.