惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Y
Y Combinator Blog
IT之家
IT之家
博客园_首页
人人都是产品经理
人人都是产品经理
博客园 - Franky
I
InfoQ
Recent Announcements
Recent Announcements
P
Proofpoint News Feed
H
Hackread – Cybersecurity News, Data Breaches, AI and More
GbyAI
GbyAI
大猫的无限游戏
大猫的无限游戏
aimingoo的专栏
aimingoo的专栏
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
月光博客
月光博客
Microsoft Security Blog
Microsoft Security Blog
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
B
Blog RSS Feed
MongoDB | Blog
MongoDB | Blog
雷峰网
雷峰网
博客园 - 聂微东
N
Netflix TechBlog - Medium
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
The GitHub Blog
The GitHub Blog
D
Docker

DEV Community

Authentication Security Deep Dive: From Brute Force to Salted Hashing (With Java Examples) Why AI Systems Don’t Fail — They Drift Spilling beans for how i learn for exam😁"Reinforcement Learning Cheat Sheet" I Replaced Chrome with Safari for AI Browser Automation. Here's What Broke (and What Finally Worked) How Python Borrows Other People's Work The $40 Architecture: Processing 1 Billion API Requests with 99.99% Uptime Vibe Coding: A Workflow Guide (From Zero to SaaS) Most webhook security guides protect the wrong side. The scary part is delivery. Headless CMS for TanStack Start: Build a Blog with Cosmic EU Age Verification App "Hacked in 2 Minutes" — What Actually Happened Comfy Cloud’s delete function does not actually remove files Running AI Models on GPU Cloud Servers: A Beginner Guide Event-driven media intelligence with AWS Step Functions and Bedrock I scored 500 AI prompts across 8 quality dimensions — here's what broke How to Call Google Gemini API from Next.js (Free Tier, No Backend Needed) The Portal Protocol: Reclaiming Human Connection in the Age of AI How to Fix Your Team's Scattered Knowledge Problem With a Self-Hosted Forum Intro to tc Cloud Functors: A Graph-First Mental Model for the Modern Cloud Designing Multi-Tenant Backends With Both Ownership and Team Access I Built a Neumorphic CSS Library with 77+ Components — Here's What I Learned PostgreSQL Performance Optimization: Why Connection Pooling Is Critical at Scale Cómo construí un SaaS multi-rubro para gestionar expensas en Argentina con FastAPI + Vue 3 🚀 I Built an Ethical Hacking Scanner Tool – Open Source Project I Replaced /usage and /context in Claude Code With a Single Statusline A Pythonic Way to Handle Emails (IMAP/SMTP) with Auto-Discovery and AI-Ready Design I Collected 8.9 Million Polymarket Price Points — Here's What I Found About How Markets Really Move EcoTrack AI — Carbon Footprint Tracker & Dashboard Everyone's Using AI. No One Agrees How. 5 self-hosted ebook managers worth trying in 2026 Building Your First AI Agent with LangChain: From Chatbot to Autonomous Assistant
What goes into utm_medium for Meta Ads — the GA4 regex th...
toshihiro sh · 2026-05-17 · via DEV Community

"We tag Meta Ads with utm_medium=social. It's a social platform, right?"

If that's been your team's convention, GA4 has been silently logging your paid clicks as organic traffic for as long as that tag has been in production. This isn't a misconfiguration or a GA4 bug — it's the result of GA4's official Paid Social regex ^(.*cp.*|ppc|retargeting|paid.*)$ OR-ing against the Organic Social rule.

This post walks through what to put into utm_medium for Meta Ads, working from the official regex GA4 actually evaluates.

TL;DR

  • Use utm_medium=cpc — shortest match for GA4's Paid Social regex
  • Never use social — collides with Organic Social and logs paid ads as organic
  • paid_social and paid-social split your reports — pick one and lock it across the org

Breakdown of GA4's official utm_medium regex — 4 alternation in one table

1. The regex GA4 actually evaluates

GA4's Default Channel Group auto-classifies each hit by utm_source + utm_medium. A session lands in Paid Social when both conditions hold:

  • utm_source matches GA4's "social sites list"
  • utm_medium matches ^(.*cp.*|ppc|retargeting|paid.*)$

The regex chains 4 alternatives with |:

  • .*cp.* — anything containing "cp" (cpc, cpm, cpa, oCPM)
  • ppc — exact match
  • retargeting — exact match
  • paid.* — anything starting with "paid" (paid, paid_social, paid-social)

Values that don't match: social, display, meta, paid social (with a space), blank.

2. How utm_medium breaks

Incident 1: utm_medium=social logs paid ads as organic

GA4's Organic Social rule matches utm_medium against social / social-network / social-media / sm. With utm_source=facebook + utm_medium=social, the Medium-only match wins — the session is classified as Organic Social. Money spent on Meta paid ads gets logged as organic traffic, and reported ROAS is understated.

Incident 2: paid_social / paid-social split, and meta falls into (other)

paid.* matches both paid_social and paid-social. Paid Social classification works, but GA4 stores dimension values with the original punctuation intact. Mixing both in delivery produces two separate Paid Social rows that need manual merge each month.

Separately, naming it utm_medium=meta ("because it's Meta Ads") matches none of the regex alternatives. The session fails the Paid Social condition and lands in (other), disappearing from the Paid Social report.

3. Recommended format and verification

utm_source=facebook
utm_medium=cpc
utm_campaign={{campaign.name}}
utm_content={{ad.name}}
utm_term={{adset.name}}
utm_id={{campaign.id}}

Enter fullscreen mode Exit fullscreen mode

Three reasons utm_medium=cpc is the safest value:

  • Guaranteed regex match: shortest fit for .*cp.* — near-zero typo risk
  • Universally readable: short for "Cost Per Click" — anyone glancing at the report instantly recognizes "paid click channel"
  • Aligned across channels: Google Ads / TikTok Ads / LinkedIn Ads all use cpc by convention — cross-channel reports stay consistent

Here's what happens with values other than cpc:

Recommended vs NG — GA4 classification by utm_medium value

Two checks before and after launch:

  1. Pre-launch URL preview: open the URL parameter field in Meta Ads Manager's ad editor, click "URL preview", confirm utm_medium=cpc shows up as expected
  2. Post-launch GA4 realtime: within 30 minutes, open GA4 → Realtime → Source/Medium and confirm facebook / cpc is showing. facebook / social or (direct) / (none) = parameter never reached GA4

Wrap-up

There's a long debate online about social vs paid_social vs cpc. But what GA4 actually evaluates is one regex: ^(.*cp.*|ppc|retargeting|paid.*)$. social doesn't match. cpc does. That's the entire story.

If you're seeing surprise rows in Paid Social or Default Channel Group's (other), audit the utm_medium values your delivery is producing.


Originally posted on RevenueScope (with the full reference list and GA4 docs source).