Why Amplitude and PostHog attribution doesn't match your ad platforms
Your Amplitude or PostHog attribution will never match Google Ads, and most of the gap is by design. Here's how to audit it per tool: which differences to expect, and which ones are real capture defects to fix.

You open Amplitude's attribution chart next to the Google Ads conversion column, and the two don't come close. Same story in PostHog. Neither tool is broken. Amplitude and PostHog disagree with your ad platforms for the same five structural reasons any product-analytics tool does: attribution model, lookback window, capture point, identity merge, and platform self-attribution.
The audit below sorts the deltas you should expect from the defects you should fix, with the checkpoints swapped for each tool's capture and identity mechanics. It's the same audit we ran against Mixpanel in Why your Mixpanel attribution doesn't match your ad platforms; if you're arriving fresh, the five causes are argued in full there, and this page recaps them in one table before getting straight to the Amplitude- and PostHog-specific checks.
#The framework in one table
| Cause | What differs | Verdict when healthy |
|---|---|---|
| Model | Your chart's first/last/multi-touch choice vs the platform's own credit rules | By design |
| Window | The tool's lookback vs the platform's click-through window; event time vs click time | By design |
| Capture point | What the SDK recorded after page load vs what the platform counted at click | Where real defects live |
| Identity merge | Anonymous-to-known stitching on the tool's ID logic vs the platform's identity graph | By design (verify config) |
| Self-attribution | View-through, engaged-view, cross-device claims the tool can't see | By design; permanent gap |
Everything below is steps 1 to 4 of the audit (UTM capture, model/window alignment, identity review, side-by-side counts), with the checkpoints swapped for each stack.
#Amplitude specifics
Capture (step 1). Amplitude's SDK captures UTM parameters and referrer into attribution user properties on new sessions. Chart your ad-sourced conversions grouped by initial UTM properties and measure the share with empty attribution, then click your own ads and confirm the parameters survive redirects, consent ordering, and any router that rewrites the landing URL before the SDK initializes. Ad-sourced users with blank attribution properties are your defect number.
Model and window (step 2). Attribution in Amplitude is largely a chart-time choice: which touch gets credit and how far back to look are analysis settings, so two teammates can build two "correct" charts that disagree with each other and with Google Ads. Write down the chart's model and lookback next to the platform's attribution setting and window, and standardize one house configuration for spend questions.
Identity (step 3). Amplitude merges anonymous device activity with the known user on identification. First-touch attribution therefore depends on how much pre-signup activity got merged. Sample converted users and check which session contributed the winning UTMs, especially for users who converted on a second device or a later visit.
#PostHog specifics
Capture (step 1). PostHog stores first-touch campaign data as
$initial_utm_source-style person properties, set from the first tracked
pageview. Same check: share of ad-sourced persons with empty
$initial_utm_*, then walk your own ad click end to end. Two
PostHog-flavored additions. If you run reverse proxying to dodge ad
blockers, verify it's actually deployed on every domain; and self-hosted
instances add their own failure mode, since an under-resourced ingestion
pipeline drops events silently.
Model and window (step 2). First-touch person properties are sticky by design (they never update after the first visit), which quietly makes "attribution" mean first ever touch unless you also model last-touch from session properties. That's a stronger first-touch bias than either Amplitude or your ad platform has; name it in the memo.
Identity (step 3). PostHog merges anonymous and identified persons on
identify calls. Merge behavior decides whose $initial_utm_* wins, so
sample merged persons the same way: did the surviving first-touch come from
the session you'd expect?
#What changed vs the Mixpanel audit
The audit steps transfer unchanged; only the checkpoints move:
| Audit step | Mixpanel | Amplitude | PostHog |
|---|---|---|---|
| UTM capture check | First-touch UTM properties | Attribution user properties | $initial_utm_* person properties |
| Model/window alignment | Attribution settings | Chart-time model + lookback | Sticky first-touch properties |
| Identity review | distinct_id merge | Device→user merge on identify | Person merge on identify |
| Side-by-side counts | Identical step | Identical step | Identical step |
| Verdict table | Identical step | Identical step | Identical step |
The delta findings from running both audits against live workspaces (which steps surfaced real defects on which stack) sort the same way every time (illustrative split; the distribution is what the audits keep producing): the UTM capture check finds most of the genuine defects on every stack, the model/window mismatch explains most of the raw count gap while being a defect on neither side, and identity merging explains the strangest individual journeys but the smallest share of the totals.
#By design vs defect: the shared verdict table
The verdict logic is identical across all three stacks. Platform total above tool total at a stable ratio: by design, document it. Ad-sourced sessions with empty attribution properties: defect, fix capture. Tool total above your system of record: defect, hunt duplicates and test traffic. Gap growing at constant spend: capture is decaying, re-run step 1. The full table (and the memo format that turns it into something you ship to your boss) is in Why your Mixpanel attribution doesn't match your ad platforms; it applies verbatim here.
#Which tool answers the spend question
Amplitude and PostHog are excellent at what they're built for: what users do after they arrive. When the recurring question is "what did the spend return", you've hit their capture boundary, not a configuration problem. The platform's claims need checking against a system of record, across channels, with values attached. Where product analytics ends and spend-side measurement begins is drawn honestly in Where Buron fits alongside your product analytics. And whatever tool sits on the product side, Buron runs the spend-side cross-check continuously (ad-platform claims against warehouse-verified conversions), so the gap this audit explains once stays explained.
Frequently asked questions
Why doesn't Amplitude match Google Ads?
Different measurement by design: Google Ads credits its own clicks with its attribution setting and windows and includes view-through and cross-device conversions, while Amplitude attributes from the UTM and referrer properties its SDK captured, under your chart's model and lookback. A stable, explained gap is normal; an unexplained or growing one is a capture defect.
Can PostHog do marketing attribution?
Within its capture boundary, yes: PostHog records initial UTM parameters and referrers as person properties, so you can attribute conversions to first-touch campaign data. It cannot see clicks that never became tracked sessions, impressions, or the ad platform's cross-device matches, so its numbers answer 'what did tracked visitors do', not 'what did the click buy'.
Do Amplitude and my ad platform count the same conversion?
Rarely one-for-one. The platform counts a conversion when it can match it to its own ad interaction (including view-through and cross-device matches), booked against click time. Amplitude counts the event when a tracked, identity-merged user performs it. Same business outcome, two counting systems; audit the gap instead of forcing a match.