Skip to main content
Terminus
Contents
The Letter and the LinkChapter 3 · ~11 min read

How a Value Behaves

Analytics reads every value literally: by the exact string, sorted as text, split where you put separators. What that means for case, dates, delimiters and the lists you allow.

On this page
The chapter in 5 min, as a video.Next video: Chapter 4 · Taxonomy Types →

The Q3 pipeline review. Priya, the VP of Marketing, pulls up the channel slide and asks: “Should we shift budget from LinkedIn to Google next quarter?”

Megan, the analyst, hesitates. She knows the LinkedIn numbers are split across four spellings, linkedin, LinkedIn, li and linked-in, and she can’t say by how much without hours of cleanup.

The room makes the call anyway. $25K moves from LinkedIn to Google.

That company is a composite of teams we’ve worked with: a 40-person B2B software firm, five marketers, about $180K a quarter of paid spend. Nobody had ever decided which values were allowed in a link.

So each marketer typed what seemed right at the time.

Chapter 2 ended on two questions: which values go in those five fields, and who decides? Most teams answer the first one with a shrug. Values are labels. Any sensible spelling will do, and lowercase, year-first dates and underscores are matters of taste.

They aren’t, because your analytics doesn’t read values the way you do.

Sort the report and look

Here’s a small campaign report, sorted A to Z by campaign, the way any report or spreadsheet sorts text:

CampaignSource
spring_sale-shoes-03_2025Facebook
spring_sale-shoes-03_2025facebook
spring_sale-shoes-09_2024facebook
summer-sale-shoes-2025_06newsletter

Three questions. Answer them before you open the reveal.

  1. How many different sources does Facebook show up as?
  2. Which spring flight launched first?
  3. A program that splits campaign names on their hyphens reads the second piece as the product. What product does it find in the last row?
Show the answers
  1. Two. Facebook and facebook are different strings, so they’re different rows, and every total for the campaign is split between them.
  2. September 2024, the lower of the two spring rows. The report sorted the characters, and 03 comes before 09, so March 2025 sits above the flight that ran six months earlier.
  3. sale. Split on hyphens, summer-sale-shoes-2025_06 comes apart into four pieces, summer, sale, shoes and 2025_06, and the second one is sale.

Look at the campaign column again. Both Facebook rows say spring_sale-shoes-03_2025, spelled exactly alike, and the source column still splits Facebook in two. Whoever made those links probably copied the campaign value from the plan and typed the source by hand. A report grouped by campaign looks clean, and the split only shows when you open its source breakdown.

Nothing in that report is broken. Every row is exactly what someone typed.

Analytics reads the string, not the meaning

The three surprises have one cause. Your analytics and every tool behind it read a value as a string of characters. It doesn’t know what you meant. It knows what you wrote.

It groups by the exact string. In GA4’s reports and in a warehouse such as BigQuery or Snowflake, Facebook and facebook are two rows. GA4’s channel rules ignore case, so both might land in the right channel, and the source column still splits in two.

One spelling, one row.

It sorts as text. A report sorts characters, not dates, and dates go wrong three ways:

  1. Month first: March 2025 sorts above September 2024 (03_2025 before 09_2024).
  2. Month names: April sorts before January (apr before jan).
  3. No zero: March sorts after October (2025_3 after 2025_10).

Only one form sorts by time: year first, zero-padded. 2025_03 for a month, 2025_q2 for a quarter, 2025_03_14 for a day.

It splits only where your separators allow. Anything that has to pull a name apart again, a spreadsheet formula or a warehouse query, needs to know where one piece ends and the next begins. So the book uses two delimiters with two jobs: underscores join the words inside one segment, and hyphens separate segments. summer_sale-shoes-2025_06 splits into three whole pieces. summer-sale-shoes-2025_06 splits into four, and no program can put summer and sale back together. Mediums follow the same rule, because a medium often ends up inside a longer name, where a hyphen would split it: it’s paid_social, never paid-social.

One fact per slot. A value carries its own slot’s fact and nothing else. If the source is facebook, the medium isn’t facebook_social. Keep each slot to its own fact and every slot can be grouped and filtered on its own; cram two facts into one and neither can.

Here’s what those rules catch on a single hand-typed link, value by value:

Typed by handFrom the list
Facebookfacebook
Social Mediasocial
Summer Sale 2025!summer_sale-shoes-2025_06

The capital letter makes a second Facebook row in every report. The spaces make another spelling of each value. And ! is outside the safe characters (letters, digits, underscores and hyphens).

A value means what you agreed, and what the tool decides

The string is what the tool sees. The meaning is what your team agreed it stands for, plus what the tool’s rules make of it.

paid_social and social are different channels because your list says so: one is a paid ad, the other an organic post. GA4 agrees: its channel rules (Chapter 2) put a paid medium from a social source in Paid Social and social in Organic Social. When the list and the tool agree, the report means what you meant.

Two things share the word channel. Dana’s channel dimension from Chapter 1 is a fact her team decides. GA4’s is the tool’s grouping of source and medium. They match only because the medium list was built to make them match. Tag a paid Facebook ad social by mistake and they come apart: the ad was paid social to Dana and Organic Social to GA4.

The medium list

This book’s mediums are written for GA4’s rulebook. GA4 calls a medium paid when it starts with paid or contains cp, like cpc (or is exactly ppc or retargeting). Then the source picks which paid channel: cpc needs a search source to land in Paid Search, paid_social a social source, paid_video a video source. A paid medium from a source GA4 doesn’t recognize lands in Paid Other. Every medium below but offline passes GA4’s default rules:

MediumUse forGA4 default channel
cpcpaid searchPaid Search
paid_socialpaid socialPaid Social
paid_videopaid video, such as YouTube adsPaid Video
socialorganic social postsOrganic Social
videoorganic video descriptions and cardsOrganic Video
emailevery emailEmail
displaydisplay and banner adsDisplay
affiliateaffiliate linksAffiliates
referralpartner links, guest posts, event appsReferral
audiopodcast show notes and adsAudio
offlineQR codes, print, events, direct mailUnassigned, unless you add a custom channel group

offline is the one deliberate exception: GA4 doesn’t recognize it, and it’s on the list anyway, because printed codes and event signage deserve their own bucket. A custom channel group gives them one.

Sources are simpler: the platform or property, lowercase.

  • Platforms: google, bing, facebook, instagram, linkedin, twitter, tiktok, youtube
  • Your own emails: newsletter, promotional_email
  • Offline: retail_display, direct_mail, print_ad, event
  • With a detail: partner-acme, affiliate-jane_smith, podcast-marketing_over_coffee

A source can add one detail after a hyphen, to name the third party that publishes the link. Where your own printed material sits is a placement, and it goes in utm_content: Stride’s QR code at Fleet Feet NYC is source retail_display, content fleet_feet_nyc-qr_code.

The two lists aren’t independent. Each medium takes only some sources: email comes from newsletter or promotional_email, never from facebook, and social comes from facebook or instagram, never from newsletter. Both values in newsletter / social are on the list, and the pair is still wrong: GA4 files any social medium under Organic Social, so the newsletter’s clicks read as organic posts. So the list holds pairs as well as values: for each medium, the sources it allows. A builder can then offer only those sources once the medium is picked (Chapter 9).

Some teams go leaner, with one paid medium and the source saying which channel: facebook plus paid is paid social, google plus paid is paid search. GA4 copes, since paid matches its paid rule. Anything that reads only the medium can’t, so a warehouse would need a lookup from source to category to tell the paid channels apart.

Either is a fine choice.

As long as it’s a choice.

Closed list or open list

Which values go in the fields is half of Chapter 2’s question. The other half is who decides, and that comes down to what happens when someone needs a value the list doesn’t have. A controlled vocabulary is the list of allowed values for each slot. It runs one of two ways:

Closed

A value that isn’t on the list isn’t used. Someone has to add new ones, and every link stays consistent.

Lean this way when many people type values, or anything parses them: every new spelling becomes a new row.

Open

Anyone types what seems right. Nothing slows a launch down, and the values drift apart.

Lean this way when one person makes every link, or when a tool holds the format and a stray new word costs little. Either way, write the list down.

Open doesn’t have to mean unformatted. A tool can hold the format on an open list: it lowercases what’s typed and turns spaces into underscores, so Spring Sale arrives as spring_sale. It can’t stop a new word, though: fb is well formed, and it still isn’t facebook.

The LinkedIn company ran open without ever deciding to, and it cost them $25K of budget moved on a number nobody could trust. A closed list needs someone who adds the values, and owning that job is Chapter 10’s subject. For now it’s one sentence:

If it isn’t on the list, ask before you use it.

One pattern for campaign names

Sources and mediums are short lists. Campaigns are the one slot where a team writes a new value for every initiative, so this is where free names do the most damage. The alternative is a naming pattern: one shape every campaign name follows.

[initiative]-[product]-[yyyy_mm]

  • spring_sale-runners-2025_03
  • webinar-product_demo-2025_04
  • brand_awareness-lifestyle-2025_04

Free names cost nothing to write and everything to read: no two people’s names sort or split the same way. A pattern costs a minute of thought per campaign and gives every name the same shape. Teams usually move through three levels:

  1. Plain names: spring_sale.
  2. Names with a date: spring_sale-2025_03.
  3. Names with several segments, like the pattern above.

If nothing ever sorts or splits your names, plain is enough.

If anything does, use a pattern.

This pattern is how Stride gives product line a home. Chapter 2 found that product line had no slot of its own; here it shares the campaign slot as its own segment, runners, and stays splittable.

The date is the launch. A running campaign keeps its value until it ends, however long it runs. Rename it in April and it becomes two strings, which means two rows, and no single row holds its total. A relaunch is the opposite case: when the sale comes back as a new flight, it gets its own launch date (spring_sale-shoes-2025_09), and the two flights sit side by side, comparable and distinct.

The pattern carries initiative, product and date. There’s no region in it.

That three-segment pattern is already a small structure, and Chapter 4 picks up the idea.

Here is Stride’s list as a live builder, built in Terminus. Open the dropdowns: these are the values Dana picked, and the only ones on offer.

Loading the live builder…

All of this happens before a single visit is recorded. The values are decided at the moment a link is made, and read at stage 3, where the visit lands:

Your situation

What you need depends on a few things you can check today:

  • If several people type values, or new values arrive often, a closed list pays for itself fastest: every new value would otherwise arrive in whatever spelling its typist picked.
  • If anything parses your names (a warehouse query, Adobe classification rules on a cid), the delimiters are what the parser depends on.
  • If your reports sort campaigns, the date format decides whether last year and this year line up.
  • Whichever analytics tool you use, its channel rules decide what your mediums mean. GA4’s are the ones above.

What changes

The decisionValues as labelsValues read literally
Spellingstyle, cleaned up latera decision about how reports group, sort and split
Who types valuesanyone, whatever seems rightfrom a list, closed or open, chosen on purpose
Campaign nameswhatever reads well that weekone pattern, with the date as the launch, wherever anything sorts or parses them
Mediumswhatever describes the channelvalues the tool’s rules understand, or your own channel groups, chosen on purpose

Read down the right-hand column. Every cell is a decision, made on purpose. Which values you pick matters less than picking them; the LinkedIn company moved $25K on a number it never decided how to spell.

Where the rule lives

Back to the pipeline review and the $25K.

After that meeting, the company did two things. It wrote down a controlled vocabulary for each parameter, and it moved all link-making into one builder whose dropdowns offered only those values. Within one quarter, duplicate source entries in its reports went from 47 to zero.

Then Megan merged the old LinkedIn rows, and the history told a different story. Per dollar, LinkedIn had produced three times the pipeline of paid search. The $25K had gone to the weaker channel, and nobody could see it until the data was clean.

The list of approved values can live in one of two places:

Beside the path

Written in a sheet, it’s a rule people have to remember every time they make a link.

Inside the path

Built into the builder’s dropdowns, a value that isn’t on the list can’t be typed.

Check yourself

Two flights of one campaign, spring_sale-shoes-09_2024 and spring_sale-shoes-03_2025, sort A to Z with the 2025 flight on top. Why, and what values would sort them by launch?

Show answer

The report compares characters, and 03 comes before 09, so March 2025 lands above September 2024. Write the year first: spring_sale-shoes-2024_09 and spring_sale-shoes-2025_03 sort in launch order.

A program splits summer-sale-shoes-2025_06 on its hyphens and reads the second piece as the product. How many pieces does it get, and what product?

Show answer

Four pieces, and the product reads sale. With underscores inside segments, summer_sale-shoes-2025_06 splits into three whole pieces, and the product is shoes.

A new hire tags a LinkedIn ad linkedin / linkedin_paid. Which rules does it break, and where do the visits land?

Show answer

The medium repeats the source, and it isn’t on the list. It also doesn’t read as paid: it neither starts with paid nor contains cp, so GA4’s paid rule doesn’t match it. The social source decides, and the visits land in Organic Social. Use paid_social.

In one line

Analytics reads a value literally: it groups by the exact string, sorts it as text and splits it where you put separators. Every convention is a decision about your reports, so make each one on purpose, and decide whether your list of values is closed.

Before the next chapter

Sort your campaign report A to Z and find one place where the order, the spelling or a split surprises you. That's a convention your team hasn't decided yet.

Next · Chapter 4 · Taxonomy TypesThen your boss asks: which campaign sold the most sneakers in Europe?