The GA4 events model, explained for people who aren't analysts
GA4 confuses everyone coming from Universal Analytics because it threw out the old model entirely. Events, parameters, custom dimensions, and key events — the whole thing in one read.
Everything in GA4 is an event. Not pageviews with some events bolted on — every single interaction, including the pageview itself, is an event with a name and a set of parameters attached to it. Once that clicks, most of GA4's odd behaviour stops being mysterious: reports are built by counting events and grouping them by their parameters, and anything you did not send as a parameter simply does not exist.
The whole data model in three concepts
Events are things that happened: page_view, scroll, add_to_cart, purchase. Each has a name.
Parameters are the details attached to a single event: page_location, value, currency, item_name. They describe that one occurrence and nothing else.
User properties are attributes of the person rather than the moment: membership_tier, account_type. They persist across that user's events.
That is the entire model. If a value describes what happened, it is a parameter. If it describes who it happened to, it is a user property. Getting that split right at design time saves an enormous amount of rework — see dataLayer design for naming conventions that survive contact with a redesign.
The four kinds of event
GA4 events come from four places, and knowing which is which tells you where to go when one is missing.
| Type | Where it comes from | Can you change it? |
|---|---|---|
| Automatically collected | Collected by the tag with no setup — first_visit, session_start, user_engagement | No |
| Enhanced measurement | Toggled on in the GA4 data stream — scroll, click, file_download, video_start, form_start | On or off, with some tuning |
| Recommended | You send them, but Google defines the name and parameters — purchase, add_to_cart, generate_lead | You implement them |
| Custom | Entirely yours — quote_requested, demo_booked | Fully |
The rule that saves the most pain: if a recommended event exists for what you are tracking, use it, exactly as specified. GA4's ecommerce reports, Google Ads conversion imports, and audience builders all key off those exact names and parameters. A custom event called order_complete will collect data perfectly well and populate absolutely nothing in the Monetisation reports.
Key events (formerly conversions)
Marking an event as a key event tells GA4 that it matters. Key events get their own columns in reports, can be imported into Google Ads as conversions, and drive most audience definitions.
Two things trip people up. First, the toggle is not retroactive in reporting terms — you are marking the event going forward. Second, GA4 renamed conversions to key events in 2026, and the naming split across the Google stack has confused a lot of dashboards; what actually broke covers it.
How events actually reach GA4
Two paths, and most sites use the second:
Direct gtag. The GA4 tag on your page calls gtag('event', …). Simple, and appropriate if you have one or two events and no tag manager.
Via the dataLayer and GTM. Your site pushes a structured object onto window.dataLayer; a GTM trigger listens for it; a GA4 event tag reads values out of it and sends the event. More moving parts, far more maintainable, and the standard for anything beyond a handful of events.
window.dataLayer = window.dataLayer || [];
window.dataLayer.push({
event: 'add_to_cart',
ecommerce: {
currency: 'USD',
value: 49.00,
items: [{
item_id: 'SKU-1189',
item_name: 'Merino Crew',
item_category: 'Knitwear',
price: 49.00,
quantity: 1
}]
}
});
Two details in that snippet matter more than they look. The window.dataLayer = window.dataLayer || [] line must run before GTM loads, or every push before initialisation is lost. And ecommerce events carry their detail in an items array, which is scoped differently from ordinary parameters — the items array deep dive explains where that distinction bites.
Why your parameter is not in any report
This is the single most common GA4 support question, and the answer is almost always the same: collecting a parameter and being able to report on it are two different things.
GA4 stores every parameter you send. But custom parameters do not appear as dimensions until you register them under Admin → Custom definitions, matching the parameter name exactly. And registration is not retroactive — data only accrues from the moment you register.
So the sequence is: send the parameter, register it as a custom dimension, wait for new data, then build the report. If you skipped step two, the data is technically in your property and reachable in BigQuery, but invisible in the interface.
The limits that quietly shape your design
GA4 is generous but not unlimited, and the ceilings matter when you plan a tracking implementation:
- 25 parameters per event. Enough for almost anything sane.
- 50 event-scoped custom dimensions and 25 user-scoped on a standard property.
- 300 distinct event names per property. Reachable if you generate event names dynamically — which you should not.
- High-cardinality dimensions collapse into an "(other)" row. Register a raw URL, a user ID, or a timestamp as a custom dimension and your real values disappear into a bucket.
That last one is the expensive mistake. Keep dimension values bounded and normalised — custom dimensions without blowing up cardinality covers how.
A naming convention that survives
Because event names are the primary key of everything downstream, decide the rules once and enforce them:
- snake_case everywhere. GA4's own events use it; mixing conventions makes reports harder to scan and joins in BigQuery error-prone.
- Object then action: cart_viewed or, better, the recommended view_cart. Consistency matters more than which order you pick.
- Never encode a value in a name. purchase_129usd creates unbounded event names. The value belongs in a parameter.
- Write it down. A tracking plan that lists every event, its parameters, and their types is what stops the fourth developer inventing a fifth name for add-to-cart.
FAQ
What is the difference between an event and a key event in GA4?
A key event is just an ordinary event you have flagged as important. The flag is what makes it eligible for conversion reporting, Google Ads import, and most audience definitions — the underlying event is unchanged.
Why can I see my custom parameter in DebugView but not in reports?
DebugView shows the raw payload as it arrives, so parameters appear there immediately. Reports can only use parameters registered as custom dimensions, and only from the registration date forward.
Do I need GTM to send GA4 events?
No. Direct gtag calls work fine. GTM becomes worthwhile once you have more than a handful of events, more than one person maintaining them, or a need to change tracking without a code deploy.
How many custom events should a normal site have?
Most sites are well served by fifteen to thirty meaningful events. Hundreds of events usually signals that page-level detail is being encoded in event names instead of parameters, which fragments reporting and burns through the 300-name limit.
Does GA4 still have bounce rate and sessions?
Sessions still exist and are derived from session_start events. Bounce rate returned as the inverse of engagement rate, which is defined by the user_engagement event rather than by a single-pageview rule. Both are outputs of the event model, not separate concepts.
Want to know whether your GA4 tag is even loading, and whether it is loading twice? The free tracking audit checks that on any URL in seconds.
See where your tracking stands
Run the same 13-check audit referenced in this post against any URL. No signup, results in seconds.