GA4 ships with over 300 recommended events. There's a recommended event for video playback, file downloads, login flows, purchases, lead generation, refunds, and dozens of e-commerce interactions most teams never need. Before you create a custom event, Google's recommended events list is almost certainly worth checking — because creating a custom event that duplicates a recommended one is one of the most common implementation mistakes in GA4.
That said, custom events are absolutely necessary for business-specific actions that Google's taxonomy doesn't cover. This guide explains when to use them, how to name them correctly, how to structure their parameters, and the mistakes that consistently create messy event schemas that are painful to work with six months later.
The Problem: Most Custom Events Shouldn't Exist
The instinct when adding new tracking is to create a new custom event. It feels clean, descriptive, and specific to the thing you're measuring. The problem is that GA4 already has names and schemas for most of the common interactions — and when you create a parallel custom name for the same action, you end up with fragmented data, inconsistent reports, and a schema that's harder for every new analyst to understand.
Consider a team that wants to track video plays on their blog. They create a custom event called blog_video_started. GA4 already has video_start as a recommended event with defined parameters (video_title, video_duration, video_percent). The custom version uses different parameter names that only this team will remember. In two years, nobody knows what blog_video_started maps to, or whether it fires consistently.
The real cost of unnecessary custom events compounds in three ways:
- Custom dimension quota. Every custom parameter you want visible in GA4 reports must be registered as a custom dimension. GA4 gives you 50 event-scoped custom dimensions per property. That quota fills up faster than most teams expect — and once it's full, new parameters log to GA4 but don't appear in any report until you delete an existing dimension.
- Messy event schema. A property with 80 custom events is much harder to maintain than one with 20. Every new analyst has to re-learn your naming conventions, and every report-builder has to guess which events are still firing.
- Harder automation. Google's ML-powered features — predictive audiences, anomaly detection — are tuned to the recommended event schema. They work better when you use standard event names.
The rule of thumb: check the GA4 recommended events reference before creating any new event. If your action maps to a recommended event, use it.
Understanding the GA4 Event Model
Every GA4 event has the same two-part structure: an event name and a collection of parameters. Parameters are key-value pairs that describe the event in more detail — what product was viewed, how long a video played, what form was submitted.
GA4 events fall into three tiers based on how they're collected:
- Automatically collected events — GA4 fires these without any configuration:
session_start,first_visit,page_view. You cannot and should not create custom events with these names. - Enhanced measurement events — Enabled in GA4 Admin → Data streams → Enhanced measurement. These fire when the toggle is on:
scroll,click,video_start,file_download. Many teams create custom events for these actions without realizing GA4 already tracks them. - Custom events — Events you define and send yourself, for actions GA4 doesn't cover in the first two tiers.
Every event also carries a set of automatically attached parameters that GA4 collects on every hit: page_location, page_title, session_id, ga_session_number, and others. You don't need to send these manually — they're appended automatically. When you're deciding which parameters to add to a custom event, only include information that GA4 doesn't already capture for you.
How to Name Custom Events Correctly
GA4 enforces a few hard rules on event names, and has additional soft conventions that matter for maintainability.
The hard rules:
- Event names are case-sensitive.
form_submitandForm_Submitare two different events in GA4. Always use lowercase. - Use only letters, numbers, and underscores. No hyphens, spaces, or special characters.
- Maximum 40 characters.
- Do not use reserved prefixes:
ga_,google_, andgtag_are reserved for Google's own use. Events with these prefixes may appear to work during testing but silently fail to process or report correctly in production. - Do not use names reserved for automatically collected events:
app_remove,app_update,error,firebase_campaign,first_open,first_visit,in_app_purchase,notification_dismiss,notification_foreground,notification_open,notification_receive,os_update,screen_view,session_start,user_engagement.
The convention that matters: verb + object in snake_case. Google's recommended events all follow this pattern, and your custom events should too. The verb describes the action; the object describes what was acted on.
- Good:
form_submit,video_play,filter_apply,search_result_click,tool_use - Bad:
formSubmit(camelCase),form-submit(hyphen),CONTACT_FORM(uppercase),clicked(verb only, no object) - Very bad:
ga_form_submit(reserved prefix),google_contact(reserved prefix)
One practical note on specificity: don't over-specify in the event name when a parameter can carry the variation. form_submit with a form_name parameter is better than contact_form_submit, newsletter_form_submit, and demo_request_form_submit as three separate events. One event name, differentiated by parameter, is cleaner and uses fewer slots.
Structuring Event Parameters
Parameters are what make an event useful beyond a simple count. A form_submit count tells you how many times forms were submitted. Adding a form_name parameter tells you which form. Adding a form_location parameter tells you where on the page it appeared.
The registration requirement. GA4 records every parameter you send with an event. But "records" and "reports on" are different things. To use a custom parameter as a dimension in GA4 reports — to filter by it, segment by it, or add it as a column — you must register it as a custom dimension in GA4 Admin → Data display → Custom definitions. Until you do that, the parameter is logged in the raw event stream and visible in DebugView, but it won't appear anywhere in the standard reports or Explorations.
Scope: event, user, or item. GA4 custom dimensions come in three scopes:
- Event-scoped — tied to a single event occurrence. Most custom dimensions are event-scoped. Limit: 50 per property.
- User-scoped — persisted against the user profile, updated each time the parameter is sent. Used for things like
account_typeorsubscription_tier. Limit: 25 per property. - Item-scoped — used exclusively with e-commerce events and the
itemsarray. Limit: 10 per property.
The 50-dimension limit fills up faster than you think. Each of your custom parameters needs one slot. A moderately complex implementation — form tracking, tool interactions, content engagement, user properties — can consume 30 to 40 slots without anyone noticing. Once you hit 50, new parameters from new events log but are invisible in reports, and the only fix is deleting an existing dimension (which removes that dimension from historical report queries too).
Two habits that help: first, check whether GA4 already has a standard parameter name for the thing you're measuring (content_type, method, search_term are pre-defined). Second, avoid creating a custom dimension for every parameter — only register the ones you'll actually filter or segment on.
Implementation: Two Approaches
Via gtag.js directly
If your site loads GA4 via the gtag.js snippet (common with direct installs or Google Ads tags), send a custom event like this:
gtag('event', 'form_submit', {
form_name: 'contact',
form_location: 'footer',
form_id: 'contact-footer-v2'
});
The first argument is always 'event'. The second is your event name. The third is an object of parameters. Keep parameter names in snake_case and avoid sending values that could contain PII — email addresses, names, or identifiers that map to a specific person.
Via GTM dataLayer push
The GTM approach is preferred for most implementations because it decouples the data collection from the tag configuration. Your developers push structured data to the dataLayer; your GTM setup reads it and fires the GA4 tag. This is the correct pattern:
// Step 1: Developer pushes the event to the dataLayer
window.dataLayer = window.dataLayer || [];
window.dataLayer.push({
event: 'form_submit',
form_name: 'contact',
form_location: 'footer',
form_id: 'contact-footer-v2'
});
// Step 2: In GTM, create:
// - A Custom Event trigger matching event name "form_submit"
// - A GA4 Event tag that fires on that trigger
// - Variables to read form_name, form_location, form_id from the dataLayer
In GTM, you'll create a GTM Custom Event trigger with the event name matching what you pushed (form_submit). Then a GA4 Event tag fires on that trigger, with the event parameters populated from Data Layer variables.
Don't forget to promote to key event when needed. A custom event fires and records in GA4 automatically. But if this event represents a business outcome you want to optimize on — a lead submitted, a trial started — you need to go to GA4 Admin → Data display → Events and toggle it as a key event. An event that never gets marking it as a key event won't appear in your Key Events report and won't be importable into Google Ads.
The Most Common Mistakes
Naming convention violations
The most common is camelCase: formSubmit, videoPlay, searchResultClick. GA4 accepts these names — they don't throw an error — but they create a messy schema alongside GA4's own snake_case recommended events. Six months later the event list has a mix of styles that's hard to maintain. The fix is to standardize to snake_case from day one.
Duplicating recommended events
As covered above: if GA4 has a recommended event for the action, use it. The most common duplicates are custom events for file downloads (GA4 has file_download via Enhanced Measurement), video plays (video_start), and external link clicks (click). Before implementing, check whether Enhanced Measurement already covers it — you might just need to enable a toggle.
Forgetting to register custom dimensions
This is probably the most painful mistake in practice. A developer implements a custom event with five parameters. The implementation looks correct in DebugView — the event fires, all five parameters appear in the event details. The team moves on. Three months later, an analyst tries to break down the event by form_name in a standard report and finds the dimension doesn't exist. The data was there all along — it just was never registered. GA4 doesn't backfill custom dimension registration; historical parameter values that weren't registered are inaccessible in reports.
Sending PII in event parameters
GA4 Terms of Service explicitly prohibit sending personally identifiable information — email addresses, phone numbers, names, user IDs that map to individuals — in event parameters. Violations can result in property suspension. The common paths for PII to end up in events: a developer includes the user's email in a user_email parameter; a form submission event captures the input value without checking whether it's an email field; a URL parameter like ?email= gets included in a page_location override.
Using high-cardinality values
GA4 caps custom dimension cardinality: dimensions with more than a few thousand unique values collapse to (other) in reports. Sending a full URL, a timestamp, an order ID, or any unique-per-event value as a custom parameter will result in most values showing as (other). Use categorical values where possible — page type rather than full URL, product category rather than product SKU.
How an Automated Audit Catches These Problems
Most of the mistakes above are invisible during implementation. An event with a camelCase name or a missing dimension registration fires without error — there's nothing in the browser console or DebugView that flags the problem. The cost only becomes visible weeks later, when an analyst runs a report and something doesn't add up.
NiceLookingData's GA4 audit checks for the full set of event-quality issues automatically: naming convention violations (camelCase, reserved prefixes, uppercase), parameters that appear in the event stream but have no registered custom dimension, potential PII patterns in parameter values, high-cardinality parameter values, and custom dimension quota consumption. It runs these checks across your live GA4 property and surfaces them with severity levels and specific remediation steps — so you're catching these issues before they become reporting problems.
Is your GA4 event schema clean?
NiceLookingData runs 61 automated checks on your GA4 property — including event naming violations, unregistered custom dimensions, PII parameter patterns, and custom dimension quota usage. Find the problems before they corrupt your reports. Run a free GA4 audit →
FAQ — GA4 Custom Events
What is a custom event in GA4?
A custom event in GA4 is any event you define and send yourself that isn't part of GA4's automatically collected or Enhanced Measurement events. You create a custom event when the user action you want to track isn't covered by Google's recommended events list. Custom events follow the same name + parameters structure as any other GA4 event, but you're responsible for defining the name, deciding which parameters to include, and registering those parameters as custom dimensions if you want them visible in reports.
How many custom events can you have in GA4?
GA4 allows up to 500 distinct event names per property. In practice, event name count is rarely the constraint — the custom dimension limit of 50 event-scoped dimensions is what most implementations hit first. Each custom parameter you want to report on consumes one slot, so a property with many custom events and many custom parameters can exhaust the dimension limit well before hitting the 500-event-name ceiling.
Do custom events need to be registered in GA4?
The event itself does not need to be registered — GA4 automatically records any event you send. However, the custom parameters attached to that event must be registered as custom dimensions (GA4 Admin → Data display → Custom definitions) before they appear as filterable dimensions in standard reports or Explorations. If you skip this step, the parameter values are logged but invisible in the reporting UI. Note that registration does not backfill historical data — you'll only see parameter values in reports from the point of registration forward.
What is the difference between a custom event and a recommended event?
Recommended events are event names and parameter schemas that Google has predefined for common actions — purchases, lead generation, sign-ups, file downloads, video plays, and hundreds of others. Using a recommended event name means GA4 recognizes and handles it specially: it may appear in dedicated report sections, work correctly with Google Ads import, and integrate with GA4's predictive features. A custom event is any name you choose for an action that the recommended list doesn't cover. The technical implementation is identical; the difference is whether GA4 has built-in handling for that event name.
Can custom events become key events?
Yes. Any event in GA4 — automatically collected, enhanced measurement, or custom — can be marked as a key event. Go to GA4 Admin → Data display → Events, find your custom event in the list (it will appear once it has fired at least once), and toggle "Mark as key event." Once marked, the event appears in the Key Events report and in conversion columns across acquisition and engagement reports. GA4 backfills key event status up to 3 days retroactively.
Analytics consultant turned founder. After years running the same GA4 and GTM audits across client engagements, Ludde built the audit into a product — so the pattern-matching takes a minute, not a meeting. More about Ludde →
Run a free GA4 audit.
Connect your Google Analytics 4 property. Our auditor runs 61 checks and gives you an instant health score with a plain-English action plan.
