Your GA4 setup tracks pageviews and clicks by default, but what about data that actually matters to your business—like customer tier, subscription status, or whether a user has access to a beta feature? Custom dimensions solve this problem. They're user-level properties you define once and attach to every event in GA4, letting you segment analysis by attributes unique to your product.
What Are Custom Dimensions in Google Analytics 4?
Custom dimensions are user-scoped properties that persist across all events for a given user.
Understand custom dimensions as user-level data
In GA4, custom dimensions live at the user level—meaning once you set a property like customer_tier: 'premium', that value attaches to all subsequent events for that user until you change it. GA4 supports up to 25 custom dimensions per property. They're different from custom event parameters, which are event-specific and don't carry forward to other events. Use dimensions for user attributes; use event parameters for transaction-level or action-specific data.
// Set custom user properties (dimensions) via gtag
gtag('config', 'G-XXXXXXXXXX', {
'customer_tier': 'premium',
'account_age_days': 156,
'feature_access_level': 'enterprise'
});
// These properties now apply to all events for this userKnow when to use dimensions vs. event parameters
Custom dimensions describe the user and don't change often (tier, region, subscription type). Custom event parameters describe the action and change per event (product clicked, video duration, cart value). If you're tracking something that carries forward across multiple events, use a dimension. If it's one-off event data, use an event parameter.
// Custom user property (dimension) — persists
gtag('config', 'G-XXXXXXXXXX', {
'customer_tier': 'premium'
});
// Custom event parameter — attached to this event only
gtag('event', 'purchase', {
'product_category': 'software',
'purchase_value': 99.99,
'currency': 'USD'
});How to Set Up and Send Custom Dimensions
Setting up custom dimensions requires two steps: registering them in GA4 admin, then sending them from your app.
Register custom dimensions in GA4 Admin
In your GA4 property, go to Admin > Data collection and modification > Custom definitions and click Create custom dimension. Give it a descriptive name (e.g., customer_tier or feature_access_level). GA4 auto-generates the parameter name—note this exact name, because you'll reference it in your gtag code. The scope is automatically set to User, which is what you want for custom dimensions.
// After registering 'customer_tier' in Admin > Custom definitions,
// send it via gtag with the exact parameter name you registered
gtag('config', 'G-XXXXXXXXXX', {
'customer_tier': 'premium'
});
// GA4 now knows 'customer_tier' is a registered custom dimensionSend custom dimensions from your application
Use the gtag library to send custom dimensions. Set them in a gtag('config', ...) call on page load or after user login, so they apply to all subsequent events. Update them dynamically whenever a user's properties change (e.g., after an upgrade). Keep dimension values consistent and use snake_case names.
// On page load or after authentication
gtag('config', 'G-XXXXXXXXXX', {
'user_id': user.id,
'customer_tier': user.subscription_tier,
'account_created_date': user.created_at,
'feature_beta_access': user.has_beta_features ? 'true' : 'false'
});
// If user upgrades, update the dimension
function upgradeUser(newTier) {
gtag('config', 'G-XXXXXXXXXX', {
'customer_tier': newTier
});
}Verify custom dimensions are being received
Open DebugView in your GA4 property (under Admin > DebugView) to see real-time events with custom dimension values. Look for the User properties card in each event to confirm your custom dimensions appear with the correct values. If a dimension isn't showing, verify the parameter name matches exactly what you registered in Custom definitions, and check that you're using the correct GA measurement ID.
// Enable debug mode to see events in real-time in DebugView
gtag('config', 'G-XXXXXXXXXX', {
'debug_mode': true,
'customer_tier': 'premium',
'account_created_date': '2024-01-15'
});
// Now go to Admin > DebugView in GA4 to see events streaming in
// Custom dimensions appear in the "User properties" section of each eventCommon Mistakes to Avoid
A few things can go wrong when implementing custom dimensions. Know these pitfalls upfront.
Don't exceed the 25-dimension limit
GA4 caps custom dimensions at 25 per property. Plan carefully—use event parameters for high-cardinality data (product IDs, timestamps, URLs) instead of dimensions. Reserve dimensions for meaningful, low-cardinality user attributes: subscription tier, region, feature access level, account type, cohort.
// ✅ Good use of custom dimensions (low cardinality, reusable)
gtag('config', 'G-XXXXXXXXXX', {
'customer_tier': 'premium', // Few distinct values
'account_region': 'us-west', // Few distinct values
'feature_access_level': 'enterprise' // Few distinct values
});
// ❌ Don't use dimensions for high-cardinality data
// Wrong: 'product_id': 'SKU-12345-67890' (thousands of distinct values)
// Wrong: 'event_timestamp': Date.now() (infinite distinct values)
// Use event parameters instead for product_id and time-based dataAlways provide explicit values—never send null or undefined
GA4 treats undefined, null, or empty string values unpredictably. If a user's tier isn't set yet, either skip the dimension entirely or send a placeholder value like 'unknown' or 'free'. This prevents GA4 from creating unexpected rows in your reports and keeps your data clean.
// ✅ Correct: always provide explicit values
const tier = user.subscription_tier || 'free';
const region = user.region || 'unknown';
gtag('config', 'G-XXXXXXXXXX', {
'customer_tier': tier,
'account_region': region
});
// ❌ Wrong: sending undefined or null
gtag('config', 'G-XXXXXXXXXX', {
'customer_tier': user.subscription_tier // If undefined, GA4 drops it
});customer_tier and feature_access_level are clearer than tier and level.Common Pitfalls
- Registering a custom dimension and sending it in code with different names—GA4 treats them as separate, and the unregistered one gets dropped.
- Sending null, undefined, or empty values as dimension values, causing GA4 to create stray dimension rows that clutter your reports.
- Using custom dimensions for high-cardinality data (product IDs, timestamps) instead of event parameters—you'll hit the 25-dimension limit and make your analysis harder to read.
- Setting a dimension once and assuming it applies to all users—dimensions are per-user, so you must set them for each user session, usually on page load or after login.
Wrapping Up
Custom dimensions in GA4 let you enrich every user event with meaningful attributes—tier, region, feature access, and more. Register them in Admin once, send them via gtag, and verify with DebugView. That's it. If you want to centralize custom dimension management across multiple tools and avoid replicating this setup everywhere, Product Analyst can help.