Operations 8 min read

Naming conventions that survive 200 campaigns and 12 clients

Across four ad platforms, the campaign name is the only join key you control. Here's a convention that still parses cleanly at 200 campaigns, and how to get a whole team to actually use it.

Nobody starts an agency planning to have eleven different ways of saying "prospecting" in their campaign names. It happens one reasonable shortcut at a time: a buyer launches at 6pm and types Acme - BF Push FINAL, a new hire copies a name from the wrong client. Six months later, the Friday reporting run involves a human reading 200 campaign names and guessing what each one meant.

A naming convention is the cheapest infrastructure an agency will ever build. It's a text format and a one-page rulebook, and it pays out on every report, audit and bulk edit you run from then on. Here's a version I've seen hold up on real client rosters: what goes in the name, in what order, and how to make it stick.

The short version

  • The campaign name is your join key. Across Meta, Google, LinkedIn and TikTok it's the only field you fully control on every platform, so design it for filtering and reporting first.
  • Use fixed fields in a fixed order, with one separator. Underscores between fields, dashes inside them, everything lowercase, dates as yyyy-qN or yyyymmdd.
  • Each level of the hierarchy answers one question. Campaign covers money and strategy, ad set covers who sees it and where, ad covers what they see and which version.
  • Enforce the rules where names get created. If the upload tool doesn't check the name, the convention won't hold past week six, however good the PDF is.
  • Clean names are what make automation possible. Reports, alerts and bulk edits can assemble themselves once names parse, and that's the real payoff.

Naming is a reporting problem

The case for naming conventions usually gets framed as tidiness, which is why it loses to every deadline. It's more useful to treat your campaign names as a database schema. Every cross-platform report your agency produces works by pulling rows from four ad platforms and joining them by client, funnel stage, audience and format. None of those platforms share an ID system. The only join key that exists on all of them, under your control, is the name string.

When names are consistent, "show me Q2 prospecting video performance for Acme across Meta and TikTok" is a filter. When they aren't, it's an afternoon: someone exports everything, eyeballs each row, and rebuilds the mapping from memory. The analyst who joined in March maps BF Push differently than the person who launched it, and the error usually surfaces as a client asking why your deck disagrees with their own platform login.

The same logic extends past reporting. Automated rules target campaigns by name match. Budget pacing groups by name. UTM parameters mirror names into analytics, where the stakes are even higher because GA4 is case-sensitive and will happily report Facebook, facebook and FB as three separate sources. So the convention is really the data model that everything downstream queries.

The anatomy of a name that parses

A parseable name has three properties: fixed fields (every name contains the same fields, none optional), fixed order (a field's position never changes, so position three is always the funnel stage), and unambiguous separators (the character between fields never appears inside a field).

On separators, the boring answer is the right one: underscores between fields, dashes inside multi-word values. Underscores survive URLs, exports and spreadsheet splits cleanly; dashes are best kept out of the separator role because they collide with date formats and compound words.³ Keep everything lowercase, and write dates in one ISO-style format (2026-q2 for periods, 20260416 for launch dates) so they sort correctly as text.³

Just as important is putting each field at the right level. The platforms give you a three-level hierarchy; use it instead of cramming everything into the campaign name:

LevelThe question it answersFields that live here
CampaignWhose money, what strategyclient · platform · objective · funnel stage · period
Ad set / ad groupWho sees it, whereaudience · targeting type · geo
AdWhat they see, which iterationconcept · hook or angle · format · version · test id

The discipline this buys you: nothing repeats across levels (the client code doesn't need to be in the ad name because the hierarchy already carries it), and every report dimension maps to exactly one field at exactly one level.

Before you lock the scheme in, write down the five filters you actually use in reports. If one of them can't be built from the name, you're missing a field.

A worked convention you can steal

Here is a complete scheme that holds up at agency scale. Adapt the vocabulary, keep the structure:

campaign {client}_{platform}_{objective}_{funnel}_{period} ad set {audience}_{targeting}_{geo} ad {concept}_{hook}_{format}_{version}_{testid} campaign acme_meta_conv_prosp_2026-q2 ad set lal-buyers_broad_us ad unboxing_speed-claim_vid-9x16_v3_t041

Every value comes from a short controlled vocabulary: prosp/retarg/retent for funnel, meta/google/li/tt for platform, two-letter ISO codes for geo. Coded fields beat free-form ones because they can be validated, since a name either matches the pattern or it doesn't.² Here's how that compares with names pulled from the wild:

Name in the wildTo specWhat was broken
Acme - Summer Sale FINAL v2 (new)acme_meta_conv_prosp_2026-q2No fields at all. "FINAL v2 (new)" is version control by vibes; nothing filters or joins.
acme_prospecting/video — broadlal-buyers_broad_usThree different separators; client and format repeated at the wrong level; splits unpredictably in any tool.
ACME_Meta_Conversions_Juneacme_meta_conv_prosp_2026-06Mixed case (a different string to GA4), funnel stage missing, "June" of which year — unsortable.

One variant worth knowing about is key-value naming (cl-acme_fn-prosp_pf-meta), where each field carries its own label.² It's more robust to parse, since fields can be reordered without breaking anything, but the names get longer and uglier. Positional naming is the right default for most agencies. I'd only switch to key-value if you're feeding names into a data warehouse that justifies the verbosity.

Which fields earn their place

Every field in the name is a tax on every person who ever types or reads it, so each one has to earn its slot. The test is simple: do you filter, group, or alert on it? Client, platform, objective, funnel stage, audience, format, version and period all pass, because they're the dimensions of every report you already make.¹ A test id passes for any team running structured experiments: it's how the three ads in a hook test find each other in the export.

The fields that don't earn their place, despite constantly sneaking in:

  • Budget amounts. They change weekly; the name doesn't. Stale data baked into a join key is worse than no data.
  • Full targeting descriptions. women-25-54-interested-in-yoga-and-pilates-us-excl-purchasers is a whole sentence. The audience code should point to a definition documented elsewhere.
  • Ad copy fragments and ticket numbers. That kind of metadata belongs in your project tool, where you can join it by name whenever you need it.
  • People's initials. Ownership lives in your workflow tool. Names outlive team membership; jk-test means nothing the quarter after JK leaves.

When in doubt, leave it out. Adding a field later to new campaigns is mildly annoying; deprecating one that's baked into 200 live names is a migration.

Making 12 people follow it

Most naming conventions fail at week six rather than at the design stage. The person who wrote the spec goes on holiday, someone launches under deadline, and the exceptions start. The consistent finding across taxonomy governance work is that enforcement has to be structural: remove discretion at the point where the name is created, instead of auditing for compliance afterwards.

What that looks like in practice:

  1. Validate at upload time. Names should be assembled from dropdowns of the controlled vocabulary, or checked against the pattern before anything goes live. This is exactly the job a launch tool should do for you. Adside's bulk upload builds the name from structured fields per client, so a malformed name can't be typed in the first place.
  2. "No name, no launch." One rule with zero exceptions, including for the founder, and including at 6pm on Black Friday. The first exception ends the convention, because every future exception will cite it.
  3. Give the vocabulary one owner. A named person controls new audience codes, new clients and deprecated values, and is the only one who can change them. Naming committees are how you end up with eleven ways to say "prospecting."
  4. Retrofit pragmatically. Apply the convention to everything new from a hard cut-over date. Bulk-rename paused and archived campaigns only where reports still touch them, and keep a small old-name-to-new-fields mapping table for the historical window you still report on. Renaming doesn't reset platform learning, but it does break anything that referenced the old string, so a full change history of what was renamed, when, and by whom is what keeps the retrofit auditable.

Put the enforcement in the tool people launch with. If the upload step doesn't check names against the pattern, expect the convention to drift within a few weeks, however clear the rulebook is.

Naming for automation

Everything so far is about preventing pain. The bigger prize is what clean names let you automate, because anything that parses can be scripted:

  • Self-assembling reports. When funnel stage is always field four, the client dashboard splits prospecting from retargeting across all platforms with zero manual mapping, and new campaigns appear in the right section the moment they launch. That's how reports that build themselves work: the report doesn't know your campaigns, it knows your schema.
  • Alerts that route themselves. "CPA up 30% on anything matching _prosp_ for client X" is one rule that covers every current and future campaign, instead of a rule per campaign that someone forgets to create.
  • Bulk edits by pattern. Pause all of last quarter's prospecting for one client: filter acme_*_prosp_2026-q1, select all, pause. It takes thirty seconds and you can't miss a campaign.
  • UTMs that can't drift. Generate utm_campaign from the same fields as the campaign name and analytics agrees with the ad platform by construction. The locked, centralized link builder that UTM governance guides keep arriving at is the same principle applied to tracking.

This is why naming pays off better than almost any other ops project an agency can run. Every automation you'll want next year assumes the name can be parsed. Build the schema once, and everything downstream (reporting, alerting, bulk operations, analytics) inherits it for free.

Frequently asked questions

Should I use underscores, dashes or pipes in campaign names?

Pick one separator between fields and a different one inside fields, then never deviate. Underscores between fields and dashes inside them is the most robust combination: underscores survive URLs and exports cleanly, while dashes inside fields don't collide with the field separator. Avoid pipes as the primary separator: they read well to humans, but they get URL-encoded into %7C in UTMs and break some CSV exports.

How long should a campaign name be?

As long as the fields require and no longer, which usually means 5 fields at campaign level, 3 at ad set level and 4 to 5 at ad level. The constraint that matters is parseability rather than character count: every field present in every name, in the same order, with no optional fields. If a name needs a sixth campaign-level field, that information probably belongs at the ad set or ad level, or in a spreadsheet instead.

Do naming conventions need to match across Meta, Google, LinkedIn and TikTok?

The field order and vocabulary should be identical everywhere; only the platform code changes. Cross-platform reporting joins on the name, so meta and google must use the same funnel codes, audience codes and date format. The one platform-specific allowance: where a platform's structure differs (Google's ad groups vs Meta's ad sets), map the levels rather than inventing new fields.

How do I retrofit old campaigns without breaking performance history?

Don't mass-rename live campaigns. Renaming doesn't reset learning on Meta or Google, but it does orphan any report, rule or UTM that referenced the old string. Apply the convention to everything new from a cut-over date, rename paused and archived campaigns in bulk where reports still query them, and keep a mapping table from old names to new fields for the historical window you still report on. After two quarters the old names age out of most reporting on their own.

Should the campaign name match the utm_campaign parameter?

Yes. Generate both from the same source fields so they can never drift. The campaign name and utm_campaign are two views of the same record; if they're typed separately they will diverge, and analytics will tell a different story than the ad platform. Keep UTMs strictly lowercase because GA4 is case-sensitive: Facebook and facebook count as two different sources.

Sources

  1. Field selection and structure for paid media naming — The Complete Guide to PPC Naming Conventions, PPC Hero
  2. Delimiter-based vs. key-value naming methods and recommended fields — Campaign Naming Conventions, Supermetrics
  3. Separator choice and ISO date formats in campaign names — Marketing Campaign Naming Conventions Best Practices, Adverity
  4. GA4 case sensitivity and controlled UTM vocabularies — An Advanced Guide to UTM Naming Conventions, Improvado
  5. Structural enforcement and taxonomy governance — UTM Best Practices for Governance & Taxonomy, Uplifter
Robin Choy

Founder of Adside. Writes about the operational side of running ads at agency scale: what to automate, what to keep human, and what the data actually says.

Names that enforce themselves

Adside applies each client's naming convention automatically at upload, so every campaign, ad set and ad is named to spec before it ever goes live.