Open any GA4 property and the default reports cover the basics well enough: pages, sessions, channels, devices. But ask a question specific to your business — "which authors drive the most engaged sessions", "do logged-in users convert at a different rate", "which form on the page actually gets submitted" — and the dropdown of dimensions simply doesn't have an answer.

That's not because GA4 doesn't have the data. In most cases it does — sitting inside the event_params of every event you send, completely invisible to Explorations, standard reports, and audiences until you register it. That registration step is a custom definition, and it takes about two minutes once you know where to look.

This guide covers what custom dimensions and metrics actually are, the scopes that determine how they behave, the setup steps, GA4's limits, and the handful of definitions almost every site benefits from creating on day one.


Why custom definitions exist

Every GA4 event — page_view, purchase, a custom event you've configured in Google Tag Manager — can carry parameters. Some are automatic (page_location, page_title). Others are ones you've added yourself, often pushed through the data layer: author_name, content_category, form_name, membership_tier.

GA4 collects all of these and stores them in the event stream regardless. But the reporting interface — standard reports, Explorations, audience builder — only lets you filter, segment, or break down by parameters you've explicitly registered as a custom dimension or custom metric. Until that registration happens, the parameter exists in the data but is functionally invisible.

If you're already on BigQuery: raw event parameters are exported to BigQuery whether or not they're registered as custom definitions in GA4 — see our guide to the BigQuery export. Custom definitions matter most for the people using GA4's own interface, not for SQL access.


Dimensions, metrics, and the three scopes

Before creating anything, it helps to be clear on two distinctions: dimension vs. metric, and scope.

A custom dimension is a descriptive attribute — text or category data, like an author name or a content type. A custom metric is a number you want to sum or average — a scroll percentage, a calculated value, a duration.

Scope determines when that value is attached and how long it sticks. This is the part most people get wrong, because picking the wrong scope means the dimension either never populates or resets when it shouldn't.

Scope

Event-scoped

The value applies only to the specific event it's attached to. Use this for things tied to a single action — the title of an article being read, the name of a form being submitted, the percentage scrolled.

Scope

User-scoped

The value describes the user and persists across sessions until overwritten — membership tier, account type, signup date. Set via user_properties, not event_params.

Scope

Item-scoped

Ecommerce only. Describes a property of an individual product in the items array — material, brand, custom product attribute — rather than the event or the user as a whole.

Scope

Custom metrics

Always event-scoped. A numeric value attached to an event — video watch duration, a calculated score, a quantity — that you want to sum, average, or chart over time.


Setting up a custom definition: step by step

The setup itself is simple — the work is almost entirely in making sure the underlying parameter is actually being sent first.

  1. 1
    Confirm the parameter is firing in DebugView Before touching custom definitions, go to Admin → DebugView and trigger the event on your site (with a debug extension or GTM preview mode enabled). Confirm the parameter — e.g. author_name — appears with the value you expect, attached to the right event. If it isn't there, the issue is in your tag setup, not GA4's configuration, and no custom definition will fix it.
  2. 2
    Go to Custom definitions In GA4, navigate to Admin → Data display → Custom definitions. You'll see two tabs: Custom dimensions and Custom metrics. Click Create custom dimension (or metric).
  3. 3
    Name it and choose scope Give it a clear display name — this is what appears in report pickers, so make it human-readable (Author Name, not author_name). Choose the scope: Event for parameters in event_params, User for user_properties, or Item for ecommerce item parameters.
  4. 4
    Map it to the event parameter In the Event parameter (or User property) field, enter the exact parameter name as it's sent — case-sensitive, and must match precisely. This is the most common point of failure: a dimension created against Author_Name will never populate if the parameter sent is author_name.
  5. 5
    Save and wait Custom definitions are not retroactive — they only populate from the moment they're created onward. Allow 24–48 hours for data to appear in standard reports, though it's often visible in real-time and Exploration reports sooner.

No retroactive backfill. If you create a custom dimension today, every event sent before today will show as (not set) for that dimension — forever. There's no way to apply a definition to historical data. This is the single biggest reason to set these up early, even if you don't need the report yet.


GA4's limits — and how to plan around them

Custom definitions are a finite resource per property, and GA4 doesn't let you delete and reuse a slot for 90+ days in some cases (the parameter name becomes unavailable for a period after deletion). Plan deliberately rather than registering parameters as they come up.

Definition type Limit per property Notes
Event-scoped custom dimensions 50 The one most teams hit first — every event_params key you want visible in reports needs one of these
User-scoped custom dimensions 25 For attributes set via user_properties — membership tier, account type, lifetime value bracket
Item-scoped custom dimensions 10 Ecommerce only — properties of items inside the items array
Custom metrics (event-scoped) 50 Numeric values you want to aggregate — scores, durations, calculated values
Item-scoped custom metrics 10 Numeric ecommerce item attributes — e.g. a custom discount percentage per item

Audit before you build. Before adding new custom dimensions, check Admin → Custom definitions for ones created months ago that show (not set) across the board — these are usually leftover from a tag that was removed or renamed, and freeing them up is easier than it sounds once you know the parameter name is no longer in use.


Custom definitions worth setting up on day one

Not every parameter deserves a slot. The ones below are the small set that pay off for almost every site, regardless of industry — and because they're not retroactive, the sooner they're in place, the more useful your historical data becomes.

Author or content owner (event-scoped)

If your site publishes editorial content, registering an author_name parameter on page_view lets you compare engagement, scroll depth, and conversion influence by writer — a report that's impossible to build from GA4's default dimensions.

Content category or section (event-scoped)

A content_category or page_section parameter (blog, product, support, pricing) turns your page-level reports into section-level reports without relying on URL pattern matching, which breaks the moment your URL structure changes.

Logged-in status or membership tier (user-scoped)

Pushed as a user_properties value when a user logs in, this is the foundation for almost every "do paying users behave differently" question. Because it's user-scoped, it persists across the session and into future sessions until it's updated again.

Form name (event-scoped)

If you have more than one form on a site — contact, newsletter, demo request, quote — a form_name parameter on your submission event is the difference between a single blended "form submissions" number and being able to see exactly which form is and isn't converting.

Scroll depth or video progress (event-scoped, custom metric)

Pushed as a numeric value (25, 50, 75, 100) alongside a scroll or video_progress event, registering this as a custom metric lets you average or bucket engagement depth directly in reports rather than treating each threshold as a separate event count.


Why a custom definition isn't showing data

This is almost always one of four things, roughly in order of likelihood:

  • It's too soon. Standard reports can take up to 24–48 hours to reflect a newly created definition, even if the underlying event has been firing correctly. Check Realtime or an Exploration first — both tend to update faster.
  • The parameter name doesn't match exactly. Parameter names are case-sensitive. ContentCategory, content_category, and Content_Category are three different things to GA4, and only one of them matches what your tag actually sends.
  • The definition was created after the events fired. No retroactive backfill — anything sent before the definition existed will permanently show (not set) for that field.
  • The parameter is being sent on the wrong event, or not at all. Go back to DebugView and confirm, event by event, that the parameter and value are actually present. If a tag was recently changed in GTM, this is the first place to check.

Using custom definitions once they're live

Once a custom dimension has data, it behaves like any built-in dimension: it appears in the dimension picker for Explorations, can be added as a secondary dimension in standard reports, and can be used to build audiences (a user-scoped membership_tier dimension, for example, makes it straightforward to build a "paying users" audience for remarketing or analysis).

The most common next step is a Free Form Exploration that breaks down engaged sessions or conversions by the new dimension — for instance, sessions by content_category, filtered to a date range, to see which section of the site is actually driving the engagement your team assumes it is.


What to do next

Custom definitions are cheap to set up and expensive to retrofit — the lack of retroactive backfill means every month without the right ones in place is a month of historical data you can't get back. Start with an audit of what's already arriving in event_params and user_properties via DebugView, register the handful that map to real business questions, and leave headroom in your 50-slot budget for what comes next.

If your tracking already runs through Google Tag Manager and a structured data layer, most of the parameters worth registering are likely already being pushed — they just haven't been claimed in GA4 yet. And if you're exporting to BigQuery, registering definitions in GA4 doesn't change what's available in SQL, but it does mean the rest of your team can answer the same questions without writing a query.

Not sure which custom definitions your GA4 setup is missing?

We audit GA4 properties to find the parameters already flowing through your event stream, map them to the business questions you actually need answered, and set up the custom dimensions and metrics to match. Book a free 30-minute audit to see what's hiding in your data.