See what I see — flip the site into its own live test environment: dataLayer, event schemas, measurement grid.
GA4 custom dimensions and metrics by scope
last verified · against GA4 custom dimensions and metrics docs as of 2026-07
Reference card for GA4 custom dimensions and metrics: scopes, registration paths, quotas, collection limits, (not set) causes, and gtag recipes for engineers.
What this is
GA4 custom dimensions and metrics register event parameters and user properties as reportable fields. Dimensions carry categorical values in one of three scopes (user, event, item); custom metrics carry numeric values and are always event-scoped.
Scopes at a glance
Scope
Reports on
Models
Registration path
Reportable in
User
Custom user properties
Durable attributes of the person: membership tier, account type, logged-in status
Free-form explorations and custom audiences only (not standard/detail reports)
Custom metric (event only)
Numerical values from event parameters
Numeric measures: score, duration, quantity
Admin > Custom definitions > Custom metrics
Reports and explorations
Use custom metrics for numeric values only. For categorical data (what text was clicked, which page was viewed) use an event-scoped custom dimension instead.
Registration fields and immutability
Scope
Key fields
Locked after save
User
Dimension name (unique; hyphens prohibited, underscores and spaces allowed), Scope = User, Description (optional), User property (references the custom user property in code)
Scope and User property cannot be changed after creation
Event
Dimension name, Scope = Event, the custom event parameter name from code
Event-scoped dimensions no longer require per-event parameter registration
Item
Dimension name, Scope = Item, Event parameter set to the item-scoped parameter name
Scope and Event parameter cannot be changed after creation
Custom metric
Metric name, event parameter, Unit of measurement, Data type (for Currency)
Scope is fixed at event; metrics have no other scope
Prerequisites before creating any definition: confirm a predefined dimension does not already exist, implement the custom parameter or user property in code, verify collection in the Realtime report, and hold Editor or Administrator access.
Quotas by scope (per property)
Definition
Standard
Analytics 360
User-scoped custom dimensions
25
100
Event-scoped custom dimensions
50
125
Item-scoped custom dimensions
10
25
Custom metrics
50
125
Calculated metrics
5
50
Collection limits
Item
Limit
User properties per property
25
User property name length
max 24 characters
User property value length
max 36 characters
Event parameters per event
25
Event parameter name length
max 40 characters
Event parameter value length
max 100 characters
Item-level custom parameters per ecommerce event
up to 27
User property names
case-sensitive
Custom metric units
Category
Options
Notes
Standard
Standard
Unitless numeric
Currency
Currency
Must also mark the metric as a cost and/or revenue metric under Data type; this controls role-based access
24-48 hours after the custom data was sent AND the definition was created
First 24 hours
Custom parameters may show (not set) during the first 24 hours after registration
Backfill
Docs state data becomes reportable 24-48h after it is sent and the definition is created; they do not document any backfill of data collected before registration. Register definitions before a launch or campaign
Causes of (not set)
Cause
Detail
No data received
(not set) is the placeholder Analytics uses when it has not received information for a dimension
Registration latency
Custom parameters may show (not set) during the first 24 hours after registration
Auto-collected events
session_start and first_visit show (not set) for a parameter not included in the triggering event
content_group
Shows (not set) on events that do not accept it or when sent empty
User ID as a dimension
Registering a user ID as a custom dimension is discouraged because it causes (not set) values
Case-sensitivity mismatch
Name in code, GTM, or Admin does not match character-for-character
Reporting notes and caveats
Topic
Behavior
Numeric coercion
Any custom-dimension value that resembles a number is treated as a number even if sent as text: '9343.324234' becomes 9343.32, '94E40' becomes scientific notation
High cardinality
Avoid dimensions with high cardinality (unique ID per user or session, timestamps); values may be condensed under the (other) row
Item-scoped placement
Item-scoped dimensions cannot be added to standard reports; analyze in free-form explorations or custom audiences
User property persistence
Once set, a user property applies to all future events for that user, including future sessions; Analytics deduplicates and collects only the modified property when a value changes. The docs do not spell out whether reports attribute the first or most-recent value
Item-scoped (not set)
The official item-scoped documentation does not specify what displays when an item in the array lacks the parameter
Archiving
Archiving an unused definition frees a slot and lets the name be reused, but it is irreversible and cannot be restored; any reports, audiences, or explorations referencing an archived definition become invalid until the definition is removed
Gotchas
(not set) on every row of a registered dimension. Cause: the name in code or GTM does not match the registered name (names are case-sensitive). Fix: make the parameter or user-property name identical everywhere, including case, and confirm collection in Realtime.
Brand-new dimension shows (not set) while data is flowing. Cause: normal registration and processing latency. Fix: wait 24-48 hours after both sending the data and creating the definition; confirm live collection via Realtime in the meantime.
Event-scoped dimension shows (not set) next to certain events. Cause: the parameter is attached to specific events, not the session, and auto-collected events never carry it. Fix: pair the dimension only with events that carry the parameter, or filter the exploration to those events.
Text value '9343.324234' or '94E40' stored as a rounded or scientific number. Cause: numeric-looking custom-dimension values are coerced to numbers. Fix: prefix categorical values with a non-numeric character so they stay text.
Values collapse under an (other) row. Cause: a high-cardinality dimension (user IDs, session IDs, timestamps) exceeds row limits. Fix: keep dimensions low-cardinality; never register unique IDs or timestamps.
Item-scoped dimension missing from a standard report. Cause: item-scoped dimensions are not available in standard reports by design. Fix: analyze in free-form explorations or via custom audiences.
Cannot add a new dimension. Cause: the scope quota is full (25 user / 50 event / 10 item / 50 metrics on standard). Fix: archive an unused definition to free a slot and reuse the name, treating it as change-managed because archiving is irreversible and invalidates existing references.
User property value truncated or dropped. Cause: a collection limit or reserved name (name max 24 chars, value max 36 chars, 25 user properties max; reserved names and prefixes rejected). Fix: keep the name at 24 characters or fewer, the value at 36 or fewer, stay within 25 properties, and avoid reserved names and prefixes.
Quick recipes
set-user-property.js
// User-scoped: persists to all future events for this user (and future sessions).
// Registers behind a User-scoped custom dimension.
gtag('set', 'user_properties', {
membership_tier: 'gold'
});
event-scoped-param.js
// Event-scoped: an attribute of a single interaction.
// Registers behind an Event-scoped custom dimension.
gtag('event', 'cta_click', {
button_text: 'Start free trial',
form_name: 'hero_signup'
});
item-scoped-param.js
// Item-scoped: extra fields inside the ecommerce items array.
// Register 'color' and 'size' as Item-scoped custom dimensions.
gtag('event', 'add_to_cart', {
currency: 'USD',
value: 29.0,
items: [{
item_id: 'SKU_123',
item_name: 'Cotton T-Shirt',
color: 'blue',
size: 'M'
}]
});
custom-metric-param.js
// Custom metrics are event-scoped and numeric only.
// Register 'score' as an event-scoped custom metric.
gtag('event', 'quiz_complete', {
score: 87
});
keep-value-as-text.js
// '94E40' would be coerced to scientific notation.
// Prefix with a non-numeric character to keep it categorical.