Blog
CookiePass and Google Consent Mode: what a consent banner does to your traffic
Published · 4 min read
We run CookiePass on this site. It is a cookie consent service that implements Google Consent Mode v2 the way Google specifies it, and that property turns out to matter more than the banner's colours: it decides what your Google tag sends on every page view before the visitor has answered, after they say yes, and after they say no. This is what that looks like from the server side, where every one of those hits passes through your container.
What Consent Mode actually changes
Consent Mode is not an on/off switch for your tags. With it in place the Google tag keeps firing on every page; what changes is a flag on each hit, and what Google does with the hit because of it. When analytics_storage is denied, the tag sets no cookies, keeps no client id between pages, and sends what Google calls a cookieless ping — a hit GA4 uses for modelling rather than for the reports you read.
The flag is a query parameter named gcs. It is two letters and two digits: the first digit is ad_storage, the second analytics_storage, 1 for granted and 0 for denied.
gcs=G100 ad_storage denied, analytics_storage denied
gcs=G101 ad_storage denied, analytics_storage granted
gcs=G110 ad_storage granted, analytics_storage denied
gcs=G111 both granted
(no gcs) no Consent Mode on the page — treated as grantedThe last line is the one people miss. A page with no Consent Mode at all sends no gcs, and Google treats every hit from it as consented. Adding a banner that implements Consent Mode therefore does not reduce what is sent — it starts telling the truth about it.
How CookiePass wires it up
Consent Mode v2 requires a sequence, not a setting. The default state has to be declared before the Google tag loads — denied, for anyone who has not chosen yet — and an update has to follow the moment the visitor decides, then be restored on every return visit. Get the order wrong and the first page view of every session goes out as consented before the banner has even rendered.
This is the sequence CookiePass produces from its own script, so nothing about it lands in your Tag Manager container:
gtag('consent', 'default', {
ad_storage: 'denied',
analytics_storage: 'denied',
ad_user_data: 'denied',
ad_personalization: 'denied',
wait_for_update: 500
});
// …the visitor accepts…
gtag('consent', 'update', {
ad_storage: 'granted',
analytics_storage: 'granted',
ad_user_data: 'granted',
ad_personalization: 'granted'
});That is the whole integration. Google's own tags honour the consent state automatically, and that includes the tags SignalHost publishes into your web container. Nothing in your server container needs a consent condition — adding one by hand is how a gated Google tag ends up with ungated event tags beside it, sending data straight to Google.
What your server container sees before and after the choice
Every hit still travels the same route: the browser posts it to your own hostname, the edge forwards it to your server container, and the container sends it on to GA4. The difference is entirely in the payload.
- Before the choice: gcs=G100 on every hit, no _ga cookie, and a fresh client id on each page. GA4 receives a cookieless ping; your container counts a request.
- After accept: gcs=G111, cookies set, and the session stitches together. From here the hits are the ones your reports are made of.
- After decline: gcs=G100 on every page, for as long as the choice stands. Enhanced measurement events — scroll, file_download, the rest — follow the same rule as page_view.
This is why the container page shows two numbers per event once a banner is in place: the hits sent with analytics consent — what Analytics will report as users and sessions — and, after the slash, everything the container forwarded. session_start and first_visit never appear in either column; Analytics derives them from flags on the first page_view rather than receiving them as events.
What it means for your traffic numbers
Expect the two columns to disagree, and expect the gap to be the most useful number on the page.
- Analytics reports fewer users and sessions than your container counts requests. The difference is the share of visitors who declined or never answered — your consent rate, measured rather than guessed.
- GA4 can fill part of that gap with behavioural modelling, once the property meets Google's thresholds. Modelled data appears in reports; it never appears in your container, because it is never sent.
- With ad_storage denied, Google Ads conversion tracking has nothing to attribute to, and the conversion linker has nothing to link. A server container does not change that, and should not: first-party does not mean consent-free.
- The banner's design is now a measurement decision. A consent rate of 60% and one of 85% are the same site with different buttons, and the gap between the two columns is where you will see which one you have.
A checklist
- Load the consent script before the Google tag. The default state must exist before the first hit.
- Open a page with the banner unanswered and read gcs on a /g/collect request in your browser's network panel. It should say G100.
- Accept, and read it again on the next page. It should say G111.
- Do not add consent triggers to anything in the server container. The web tag already carries the state.
- Come back to the container page a day later and read the pair of numbers on page_view. The first divided by the second is your consent rate.
We picked CookiePass because it does exactly the sequence above, was live on this site in an afternoon, and lets the banner take the site's own colours. The numbers in the previous section are how we know it works.
