GA4 offers two ways to capture additional data beyond standard fields: custom dimensions and custom metrics. Developers often mix them up, sending numeric data as dimensions or text data as metrics, which breaks reporting. GA4 has strict quotas (50 event-scoped custom dimensions, 25 user-scoped, 50 event-scoped metrics per property), so wasting slots on incorrectly configured parameters is costly. This guide clarifies when to use each type and the most common implementation mistakes.

Custom Dimensions: What They Are

Custom dimensions are categorical or text-based attributes you attach to events or users. They answer “what kind” or “which” questions. Examples: user_type (free/paid), content_category (blog/product/landing), ab_test_variant (control/treatment), subscription_tier (basic/pro/enterprise).

Dimensions are used for segmentation and filtering in GA4 reports. You slice your data by dimension values: “Show me conversions where ab_test_variant = treatment.”

Event-Scoped vs User-Scoped Custom Dimensions

  • Event-scoped: Attached to a single event. Different events can have different values. Use for: page_type, button_label, product_category, video_title.
  • User-scoped: Attached to a user permanently (or until changed). Applies to all future events from that user. Use for: user_segment, account_type, registration_date, cohort.
// Event-scoped custom dimension: page_type
gtag('event', 'page_view', {
  page_type: 'product_listing',  // Different on each page
  page_category: 'electronics'
});

// User-scoped custom dimension: customer_tier
gtag('set', {
  user_properties: {
    customer_tier: 'premium',  // Set once, applies to all events
    signup_method: 'google_oauth'
  }
});

Custom Metrics: What They Are

Custom metrics are numeric values you want to aggregate (sum, average, count) across events. They answer “how much” or “how many” questions. Examples: video_watch_seconds, scroll_depth_percent, items_in_cart, article_word_count, form_fields_filled.

Metrics are used for calculations and aggregations: “What’s the average video_watch_seconds for users who converted?”

// Custom metric: reading_time_seconds
gtag('event', 'article_read', {
  reading_time_seconds: 245,  // Numeric, will be summed/averaged
  scroll_depth_pct: 87,
  words_read: 1200
});

// GA4 can now report:
// Average reading_time_seconds per article
// Sum of words_read per user segment
// Correlation between scroll_depth_pct and purchase

The Most Common Mistakes

Mistake 1: Sending Numbers as Dimensions

If you register “price” as a custom dimension instead of a custom metric, GA4 stores it as text. You can’t compute average price or sum revenue. You can only filter “where price = 99.99” — which is useless for analysis.

// WRONG: price as dimension
// GA4 Admin: "price" registered as Event-scoped dimension
gtag('event', 'view_item', { price: 99.99 });
// GA4 stores "99.99" as a string — can't sum or average

// CORRECT: price as metric
// GA4 Admin: "price" registered as Event-scoped metric (Currency type)
gtag('event', 'view_item', { price: 99.99 });
// GA4 stores 99.99 as a float — can sum, average, compare