pickuma.
Meta

Tracking Traffic Attribution Across Seven Audiences: What Works and What Fails

How we attribute clicks across seven distinct reader segments on pickuma.com — server-side redirects, GA4 reconciliation, where the data lies, and which channels we keep funding.

7 min read

Attribution is the layer that decides whether you double down on a channel or kill it. We run pickuma.com across seven distinct audiences — readers who land on the site through very different routes and read it with very different intent — and the gap between what each one reports and what actually drives clicks on our affiliate links is wider than most analytics dashboards suggest.

This post is the working notes from six months of tagging, breaking the tagging, and re-tagging. We walk through which audiences gave us clean attribution, which ones lied, and what to do about the gap.

The seven audiences we segment

Our setup is unglamorous on purpose: GA4 for top-of-funnel sessions, Supabase for click events on every /go/<slug> affiliate redirect, and a nightly join job that stitches the two together by UTM string. The seven audiences:

  1. Search-intent readers arriving from Google, Bing, or DuckDuckGo
  2. Direct visitors with no referrer (bookmarks, typed URLs)
  3. Bluesky followers clicking through from our cross-posts
  4. dev.to readers who came via the syndicated mirror
  5. Mastodon followers from toot cross-posts
  6. Yandex and Seznam users reached through IndexNow-pinged search engines
  7. Inbound referrals from other newsletters and blogs

Each gets a distinct UTM combination on every outbound link we publish. The article footer uses utm_source=article-footer&utm_medium=internal&utm_campaign=tools-mentioned, the dev.to body footer uses utm_source=devto&utm_medium=crosspost&utm_campaign=blog, and the Bluesky link card carries utm_source=bluesky&utm_medium=social&utm_campaign=blog-crosspost. The full UTM table lives in our internal docs and gets reviewed any time we add a new surface.

What works: server-side redirects and first-party events

The cleanest data we get is from our own redirect endpoint. Every affiliate link on the site routes through /go/<slug>, which reads the partner URL from a Supabase table and logs the click — UTM params, country, user agent, timestamp — before issuing a 302 to the partner.

Three things make this reliable:

  • No ad blocker interference. A first-party redirect is not blocked the way third-party tracking pixels are. uBlock Origin and Brave Shields do not touch /go/notion.
  • No JavaScript dependency. The click is logged on the server before the redirect. If GA4 fires, great; if it does not, we still have the click row.
  • UTM passes through. When a reader hits /go/notion?utm_source=devto&utm_medium=crosspost, those params land in the Supabase row, so we can attribute the click back to the originating syndication post.

When we cross-reference Supabase click rows against GA4 sessions for the same hour, GA4 typically undercounts by roughly 18 to 34 percent depending on the audience. dev.to readers are the worst offender — many run extensions that strip referrers entirely, and a meaningful fraction block the GA4 beacon outright.

Notion

We keep our attribution scratchpad — UTM conventions, source-by-source reconciliation queries, channel kill criteria — in a Notion database the whole team can edit. The free tier handles it for a small content team.

Free for personal use; paid plans from $10/mo

Try Notion

Affiliate link · We earn a commission at no cost to you.

What fails: dark social, organic queries, and platform-stripped UTMs

Three audiences lie to you, and you need to know which way they lie before making decisions.

Organic search readers. Google passes (not provided) for the actual query, so you cannot tell which keyword drove a click. Search Console plugs part of this hole, but the join between Search Console impressions and GA4 sessions is fuzzy — same-day aggregation only, no user-level fidelity. We accept that the keyword data is approximate and use it for trend direction, not for ranking ROI calculations.

Dark social readers. Direct traffic with no referrer is partly real bookmark visitors, but in our data a meaningful slice is actually “someone shared the URL in Slack, Discord, or iMessage.” There is no way to tag this after the fact. The only fix is to put UTM params on the canonical share buttons in your article header, so when readers click share they propagate a tagged URL. We added this in March; dark social as a share of direct traffic dropped from roughly 71 percent to 49 percent over six weeks.

Mastodon and Bluesky URL handling. Both platforms strip query parameters in some preview contexts. When the link card in a Bluesky post is what gets clicked, the UTM survives; when the reader copies the URL out of the post body, often it does not. We measured roughly 12 percent of social clicks arriving without their UTM intact. Not a crisis, but enough that you should not treat social attribution as exact.

Reconciliation and kill criteria

We run a nightly script that joins three tables: GA4 export, Supabase clicks, and our content table keyed by post slug. For each post the job produces a row with sessions, click-through to any affiliate, click-through by audience, and a delta column that flags posts where GA4 sessions exist but no Supabase clicks fired. That delta is usually the sign of a broken affiliate redirect or a missing inline CTA.

The job is around 180 lines of TypeScript. It is not sophisticated. What makes it useful is that it runs every night and surfaces three numbers per article: what came in, what converted, and where the gap is. We caught a regression last month where one of our affiliate slugs was returning 410 because we had paused the link in Supabase but not removed it from the article body — the join job flagged six posts losing clicks to nothing.

After six months we have enough data to make calls. Our criteria for keeping a syndication channel:

  • Cost per published article (including our own time) under 90 seconds
  • At least 1.5 percent click-through from session to /go/<slug> event
  • Tracking that survives the round trip long enough to attribute

dev.to passes on all three. Bluesky passes on the first two, helped by an audience that skews technical. Mastodon passes on cost — the cross-post script paces at 15 seconds per article — but conversion is weak, under 0.4 percent CTR over the last 90 days. We let Mastodon keep running because cost is near zero, but it does not get headline attention in our weekly review.

FAQ

Do I need GA4 if I already log clicks server-side? +
Yes — for top-of-funnel session data and bounce behavior. Server-side click logs only see the conversion event, not the read-then-leave pattern. Use both and reconcile nightly.
Should I use a third-party attribution tool? +
Not until your traffic volume justifies the spend. Our entire stack is GA4 free tier plus Supabase free tier plus a 180-line join script. Most paid attribution platforms optimize for problems you do not have at small to mid scale.
How do I handle UTM-stripped clicks from social platforms? +
Accept the floor. Bucket untagged inbound from a known social referer (when the referer header is present) as 'social-untagged' rather than letting it default to 'direct'. You recover some attribution without pretending you have perfect data.

Attribution is not a solved problem. It is a habit of measuring honestly, accepting where the data is fuzzy, and building the cheapest possible reconciliation job that surfaces the gap. The seven audiences above each need a different posture — and the only way to learn which is which is to run them long enough for the numbers to stabilize.

Related reading

See all Meta articles →

Get the best tools, weekly

One email every Friday. No spam, unsubscribe anytime.