Someone asks why session_start is missing. DebugView has it, once per visit, right where it
should be. The Network tab has a page_view, a scroll, a purchase — and no
session_start, however long you scroll. Tag Assistant agrees with the Network tab. So does every
other tool that reads requests.
Both are right. They are answering different questions, and the gap between them is how GA4 is built.
Where the two events come from
Google lists session_start and first_visit among the events GA4 collects
automatically: with the Google tag on the page, there is no code to write. What it does not dwell on is that
the browser never sends either of them by name.
What it sends is three flags on an ordinary hit — the first one of the session, which is normally the
page_view:
_ss=1— session start. This hit opened a session. GA4 recordssession_startfrom it._fv=1— first visit. The tag had no client ID for this browser yet: a first visit, or one after the cookies were cleared. GA4 recordsfirst_visitfrom it._nsi=1— new session ID. Thesidon this hit is new.
Google’s own help comes closest to saying it in its notes on consent, where it writes of “the initial event with the session_start parameter”. A parameter on an event: that is exactly what the request shows.
DebugView shows what GA4 recorded. The Network tab shows what the browser sent. For almost every event
those are the same thing. For session_start and first_visit they are not, and
looking for either in the requests is looking in the one place they have never been.
The rest of the session, on the same hit
The flags sit next to the values that say which session it is. sid is the session ID, which
Google describes as the timestamp in seconds when the session started. sct is the session
number for this browser, so a hit with _fv=1 should have sct=1. seg is
whether the session counts as engaged yet. By default a session ends after 30 minutes without activity; the
next hit after that carries _ss=1 and a new sid, on whatever event it happens to be.
The GA4 parameter reference lists all of them.
Do not send one yourself
The usual reaction to a missing session_start is to add one: a GA4 event tag in GTM named
session_start, fired on page load. It does not help, for two reasons Google states plainly.
Both names are on GA4’s list of reserved event names, kept for the events it collects itself. And sessions
are not counted from that event at all: Google says it counts them by estimating the number of unique session
IDs. A hand-made session_start carries the same sid as the hit beside it. It adds an
event, not a session.
If a container already has such a tag, it is worth removing before anyone builds a report on it. Reading the container finds it faster than the interface does.
When the session starts on something else
The flag goes on whatever hit opens the session, and that is not always a page_view. Google’s
explanation of (not set) says the landing page is (not set) when a session does not have a
page_view event — so the hit carrying _ss=1 is the first place to look. If its
en is scroll, user_engagement or a click, the page_view that
should have opened the session came later, or never came.
Consent is the usual reason. Google names two cases: setting every consent value with the
default command, including the ones that should be updates, which loses the initial event with
the session start on it; and events sent as denied after the visitor had granted, which GA4 counts as a
separate session with no session_start. Debugging
Consent Mode from the requests shows how to tell the two apart. The landing hit is also where the campaign
is — inside dl — which the campaign guide
reads.
Seeing it in Tag Master
Open the first GA4 hit of the visit in the Network tab. The Page & session group lists
_fv, _nsi and _ss beside the session ID, with the time the session
started worked out from it, the session count read as “Session number 1 for this browser”, and the
engagement flag. The ? beside each key says what it is.
The Audit tab checks the other half. When the hit that opened a session is not a page_view, it
says so — “Session started on scroll, not page_view” — with the property it happened to and a link that
filters the Network tab to those hits.
Questions
Why does session_start not show up in the Network tab?
Because no request carries that name. The first hit of a session — normally the page_view — carries _ss=1, and GA4 records session_start from it. DebugView shows the event because it shows what GA4 recorded, not what the browser sent.
Where does first_visit come from in GA4?
From the same hit. When the Google tag has no client ID for the browser yet, the hit carries _fv=1 as well, and GA4 records first_visit from it. Google lists it among the events collected automatically, with no code to write.
Should I send a session_start event from GTM?
No. Google lists session_start and first_visit as reserved names, and it would not add a session anyway: Google counts sessions by estimating unique session IDs, not by counting session_start events.
Why is my GA4 landing page (not set)?
Google’s explanation is that the landing page is (not set) when a session has no page_view event. Find the hit with _ss=1 and read its en: if the session opened on a scroll or a click, the page_view came late or not at all.
The rest of this group: GA4, server-side and attribution
- Debugging GA4 when DebugView shows nothing
- GA4 counting everything twice
- How to debug server-side GTM
- Google Tag Gateway: checking that it actually works
- When GA4 says the traffic came from somewhere else
- The email that left in plain text
- The em on a GA4 hit is not Enhanced Conversions
More in GA4, server-side and attribution
Try it on your own site
Tag Master is free, needs no account, and collects no data.
Add to Chrome — Free