What each one is doing that the other isn't
Both parameters describe where a click came from, but they work at different zoom levels. utm_source names one specific place: a platform, a publication, a list. utm_medium names the category that place belongs to, shared across many sources. That difference in zoom level is the whole reason both fields exist instead of one.
The practical consequence is this: utm_source is what you compare, utm_medium is what you roll up. If the question is "is Instagram or TikTok sending better organic traffic," you filter by source. If the question is "is paid working at all this quarter," you group by medium and ignore which platform did the work. Most reporting confusion comes from teams building a report that can answer one of those questions and assuming it answers both. It doesn't. Getting the medium field wrong doesn't just mislabel a row, it breaks the roll-up question specifically, while leaving the comparison question mostly intact.
The two fields, side by side
| Parameter | Answers | Value type | Example values |
|---|---|---|---|
| utm_source | Which specific place sent this click | Open. One value per platform, list, or partner | instagram, google, weekly-newsletter, partner-bloggerx |
| utm_medium | What category of channel that place belongs to | Closed. A short list you define once and reuse | social, email, cpc, referral, affiliate, qr, sms |
Notice the value type row. utm_source is meant to grow, a new source for every new platform or partner you add. utm_medium is meant to stay small, closer to ten values than a hundred, because the moment you start inventing a fresh medium per campaign, the roll-up question stops working. A medium value like "spring-sale-2026" tells you nothing when you're trying to compare paid against organic across a full year.
What to put in utm_medium
Pick from a list you wrote down before you needed it, not one you invent while pasting a link into a caption box. The list below covers what almost every team needs. Add to it rarely, and never rename an existing value once campaigns have already used it.
| Channel | Typical utm_source examples | Correct utm_medium |
|---|---|---|
| Paid search | google, bing | cpc |
| Paid social | facebook, instagram, tiktok | paid-social |
| Organic social post | instagram, tiktok, linkedin | social |
| Link in bio | instagram, tiktok | bio |
| Email newsletter | weekly-newsletter, klaviyo | |
| SMS campaign | attentive, klaviyo-sms | sms |
| Affiliate or partner link | partner-name | affiliate |
| QR code on print | flyer, poster, storefront | qr |
| Guest post or press mention | publication-name | referral |
Two rows above are worth pointing out on purpose. Paid social and organic social share sources (both might say instagram) but split on medium, which is exactly the point: the source tells you the platform, the medium tells you whether you paid for the placement. And bio link traffic gets its own medium rather than being folded into "social," because a link-in-bio click behaves differently from a scroll-past feed click. If you route both through the same medium value, you lose the ability to see whether your bio link is actually converting better or worse than in-feed placements.
Where teams actually get this wrong
- Putting the platform name in both fields. utm_source=instagram and utm_medium=instagram tells you nothing the source alone didn't already say, and it wastes the field that was supposed to let you roll up across platforms.
- Inventing a new medium per campaign. "black-friday-push" is a campaign name, not a channel type, and it belongs in utm_campaign. Put it in the wrong field and the medium list grows unbounded, which undoes the point of keeping the list closed in the first place.
- Casing that drifts. "Email," "email," and "EMAIL" read as three separate values to most analytics platforms, not one, and a campaign fragments into rows nobody thinks to add back together.
- Leaving utm_medium blank. The click still gets logged, but most platforms fall back to a generic bucket like referral or direct instead of grouping it correctly. That fallback is easy to miss until a report looks strangely thin.
How this plays out in real analytics tools
This isn't just a labeling convention, it changes how your traffic gets classified. Google Analytics 4 uses medium values, often paired with source, to sort sessions into its default channel groups automatically: a medium that matches its paid-search patterns lands under Paid Search, a medium of "email" lands under Email, and so on. Use a medium value the platform doesn't recognize and the session usually still logs, it just lands in a catch-all group like Unassigned instead of the bucket you meant. The source field has no equivalent classification role in most tools; it exists for filtering and comparison, not sorting into buckets. That is the concrete reason medium deserves the shorter, stricter list and source doesn't.
On the tracking side, this only matters if something is actually reading the parameters off the click. Raydar's link analytics record utm_source and utm_medium separately on every click through a bio link or short link, alongside referrer and first-touch and last-touch attribution, so a report can filter by source and roll up by medium without extra setup on your end. Building the links consistently in the first place is still on you, which is where a shared naming pattern earns its keep, covered in more depth in UTM naming conventions.
A worked example
Say a shoe brand runs three things this month: an Instagram feed post, an Instagram paid ad with the same creative, and a partner blog post linking to the same page. Tagged correctly, the three links look like this.
| Placement | utm_source | utm_medium |
|---|---|---|
| Organic Instagram post | social | |
| Paid Instagram ad | paid-social | |
| Partner blog post | runnersweekly | referral |
Filter by utm_source=instagram and you see both Instagram placements together, organic and paid, which is useful for "how is Instagram doing as a platform." Roll up by utm_medium=social versus utm_medium=paid-social and you can see whether the paid spend is actually outperforming the free post, which the source filter alone can't tell you, since both rows share the same source. That's the two-fields-answer-two-questions idea, worked through on one campaign instead of in the abstract.
When a platform fills in the medium for you
Meta and Google both offer built-in UTM auto-tagging inside their ad managers, and it's worth knowing before you override it by hand. Meta's automatic option typically sets utm_source=facebook or utm_source=instagram and utm_medium=paid or cpc depending on the setting chosen. Google Ads has its own auto-tagging system built around a gclid rather than UTM parameters at all, though it can be configured to add UTMs alongside it. The failure mode here isn't the auto-tagging itself, it's a person adding a second, manual set of UTM parameters on top of the URL the platform is already tagging, which produces a URL with two utm_source values and unpredictable results depending on which one the receiving analytics tool reads first. If a platform offers to tag the link for you, check what it actually writes before also typing your own values into the same field.
Checking what's already live
Before writing a new convention, it's worth knowing what's already out there. Pull a handful of your most-used links and run them through a link decoder to see the exact source and medium values currently attached, rather than assuming they match what you think you tagged months ago. It's a common discovery that three "the same" campaigns are tagged three different ways, which is usually the moment a team decides a written convention is worth the hour it takes to set up.
If you're building the link by hand
Get the pattern right once and copy it, rather than retyping utm_source and utm_medium from memory every time. A UTM builder removes the retyping entirely and keeps casing and spelling identical across every link a team produces, which matters more than it sounds like it should, since a single stray capital letter is enough to split a campaign's data in two. For the mechanics of actually attaching the parameters to a URL, including what to do when the destination link already has a query string, see how to add UTM parameters to a link. And if the five parameters themselves are still unfamiliar, what are UTM parameters covers all five from the start.