Privacy rules tightened. Ad platforms changed. I still need clean reporting and steady pipeline math. Consent Mode v2 is the bridge. When I set it up right, GA4 and Google Ads keep working when users say no, and they work even better when users say yes. That balance is the point.
Note: This guide is informational and not legal advice.
Google Consent Mode v2 setup guide
TL;DR summary for busy B2B teams
- Who needs this: Any site with users in the EEA or UK that runs GA4 or Google Ads.
- What changed in v2: Two new consent types join ad_storage and analytics_storage: ad_user_data and ad_personalization.
- Why I care: I keep measurement continuity with modeled conversions via conversion modeling, preserve remarketing eligibility when users grant consent, and reduce data gaps that wreck ROAS analysis.
Quick prerequisites
- Pick a Google-certified CMP. For serving Google Ads to users in the EEA and UK, this is required by Google policy. See Choosing your Consent Framework and Use an integrated CMP partner to set up your consent banner and consent mode.
- Decide your tag stack: GTM or gtag.js. Both work. Do not run both for the same property.
- Gather IDs: GA4 Measurement ID, Google Ads Conversion IDs and Labels.
- Define regions: Apply defaults for EEA and UK only, not worldwide.
- Plan rollout and testing: Stage, then production with a soft launch window. Include analytics and media teams in the review loop.
Simple architecture, one-screen version
- CMP banner
- -> Consent defaults set to denied at page start
- -> User choice updates consent signals
- -> GA4 and Google Ads tags adjust behavior
- -> Reporting uses cookieless pings plus modeling when needed

If I have EEA or UK traffic and any budget in Google Ads, I consider this essential. If I only use GA4, I still gain modeled metrics that keep trend lines stable when users decline analytics cookies. It may feel like added complexity, but with a small, repeatable setup it reduces support tickets later.
How I set up Consent Mode v2
Here is the simple path that mirrors Google guidance while keeping real-world steps.
1) Set default consent to denied before any tags load
Default states must be applied at the earliest possible moment on every page. In GTM, I use a Consent Initialization event. With gtag.js, I place the inline call before the Google tag.
2) Connect the CMP to send updates
When the user makes a choice, the CMP should fire one update with the four states. No extra page reloads. No race conditions.
3) Map CMP categories to Google consent types
- Advertising -> ad_storage
- Analytics -> analytics_storage
- Remarketing/user data -> ad_user_data
- Personalization -> ad_personalization
I keep names consistent across environments.
4) Configure tags to respect consent
GTM has built-in consent checks. I turn them on for every tag. If I use gtag.js, I honor consent before calling config and conversion events. Learn more about tag behavior.
5) If using Advanced mode, enable helpers
I enable URL passthrough and ads data redaction. These flags support Ads modeling and help prevent cookie writes before consent. They do not override consent. See the Impact of Consent.
6) Publish and verify
I use Tag Assistant and network checks to confirm consent states and request parameters. See GTM’s Verify Implementation.
Example defaults with region scope, executed at the very start
gtag('consent','default',
{
'ad_storage':'denied',
'analytics_storage':'denied',
'ad_user_data':'denied',
'ad_personalization':'denied'
},
{ 'region':['AT','BE','BG','HR','CY','CZ','DK','EE','FI','FR','DE','GR','HU','IE','IT','LV','LT','LU','MT','NL','PL','PT','RO','SK','SI','ES','SE','IS','LI','NO','GB'] }
);
Advanced vs. Basic, in plain speech
- Basic mode holds all Google tags until the user clicks the banner. Nothing goes out before that click.
- Advanced mode loads tags early with consent denied, sending cookieless pings. When the user grants consent, tags send full data. That early ping improves modeling and tends to improve advertiser accuracy. If legal and product agree, Advanced is often the sweet spot.
I also make sure my plan explicitly references the Consent Mode v2 parameters ad_user_data and ad_personalization. The names matter, and so does the policy behind them.
IAB TCF 2.2 Consent Mode v2 setup
If I choose the CMP partner path, I am on the track Google prefers.
- I choose a Google-certified CMP and enable IAB TCF 2.2. See Use an integrated CMP partner to set up your consent banner and consent mode.
- I ensure Google vendors are enabled in the vendor list (both Google Ads and Google Analytics).
- I map CMP toggles to Google consent types one to one. The CMP should emit a consent update event and call:
gtag('consent','update',{
'ad_storage': 'granted' or 'denied',
'analytics_storage': 'granted' or 'denied',
'ad_user_data': 'granted' or 'denied',
'ad_personalization': 'granted' or 'denied'
});
- I scope by region. I run defaults for EEA and UK only. Outside those regions, defaults can be granted if policy allows.
- I handle partial consent cleanly. If a user grants analytics but denies ads, GA4 pings become full while Ads tags keep to cookieless behavior.
In my experience, this is the most reliable CMP integration for Consent Mode v2, especially when media budgets touch the EEA and UK.
GTM Consent Mode v2 implementation
This route gives me more control and cleaner audits. For broader background, see Unblock tags with a Consent Management Platform.
1) Create a Consent Initialization tag
I use a Custom HTML tag that fires on Consent Initialization on All Pages:
<script>
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('consent','default',{
ad_storage:'denied',
analytics_storage:'denied',
ad_user_data:'denied',
ad_personalization:'denied'
});
</script>

2) Add Google tag, GA4 Configuration, and Conversion Linker
I place the Google tag or GA4 Configuration tag after Consent Initialization. I add Conversion Linker so Ads and GA4 have consistent attribution when consent is granted.
3) Use Consent Settings in GTM
For each tag, I open Consent Settings and check the required consent types. This ensures tags will not fire when a needed consent is denied.
4) Ingest CMP outcomes and dispatch updates
The CMP can push a structured event to the dataLayer or expose the TCF API. I listen for that event and fire a Custom HTML tag that calls the consent update shown above.
5) Handle Ads correctly
For Google Ads Consent Mode v2 integration, I let conversion tags fire with consent granted. When consent is denied, I still get cookieless pings that feed modeled conversions in Google Ads.
6) Use region conditions
I create a variable or server-side flag to identify EEA and UK traffic. Then I apply trigger conditions so default consent runs only where required.
Practical tip: open GTM’s Consent Overview to audit every tag’s consent checks. It is the fastest way to spot a tag that ignores ad_user_data or ad_personalization. If you prefer a ready-made starter, here is how to import a container and a workspace to try: Download .zip. For deeper context, see the Definitive Guide to Tag Manager and Complianz.
Consent Mode v2 with gtag.js
No GTM? If I keep the order precise, I am fine.
1) dataLayer and default consent first
<script>
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('consent','default',{
'ad_storage':'denied',
'analytics_storage':'denied',
'ad_user_data':'denied',
'ad_personalization':'denied'
}, { 'region':['AT','BE','BG','HR','CY','CZ','DK','EE','FI','FR','DE','GR','HU','IE','IT','LV','LT','LU','MT','NL','PL','PT','RO','SK','SI','ES','SE','IS','LI','NO','GB'] });
</script>
2) Load gtag.js
<script async src="https://www.googletagmanager.com/gtag/js?id=G-XXXXXXX"></script>
3) Configure GA4 and Ads after the script
<script>
gtag('js', new Date());
gtag('config','G-XXXXXXX');
// Ads conversion config if used
// gtag('config','AW-YYYYYYY');
// Optional Advanced mode helpers
gtag('set','url_passthrough', true);
gtag('set','ads_data_redaction', true);
</script>
4) On CMP callback, send a single update
<script>
// From the CMP callback
gtag('consent','update',{
'ad_storage': 'granted' or 'denied',
'analytics_storage': 'granted' or 'denied',
'ad_user_data': 'granted' or 'denied',
'ad_personalization': 'granted' or 'denied'
});
</script>
Common bug to avoid: never include the Google tag twice. That creates duplicate hits and messy consent states.

Cookie banner Consent Mode v2 configuration
If I maintain my own banner, I keep the mapping simple and predictable. Developer reference: Set up consent mode on websites.
Mapping of banner toggles to consent types
- Analytics -> analytics_storage
- Advertising -> ad_storage
- Personalization -> ad_personalization
- User data or remarketing -> ad_user_data
Emit one update on user action
gtag('consent','update',{
'ad_storage': adChecked ? 'granted' : 'denied',
'analytics_storage': analyticsChecked ? 'granted' : 'denied',
'ad_user_data': userDataChecked ? 'granted' : 'denied',
'ad_personalization': personalizationChecked ? 'granted' : 'denied'
});
For EEA and UK Ads, a TCF 2.2-compliant banner from a certified CMP reduces risk and helps Ads recognize consent signals reliably. If you manage consent with Site Kit, see the companion guide: A Complete Guide to Install Site Kit and Configure Google Consent Mode with Complianz.
GA4 Consent Mode v2 configuration
GA4 does two things under Consent Mode. It sends cookieless pings when analytics_storage is denied, then fills gaps using modeled conversions. When the user grants consent, GA4 switches to full measurement in the same session.

Actions I take
- Confirm the GA4 tag respects consent. In GTM, I open the GA4 Configuration tag and verify consent checks. With gtag.js, I ensure the config call happens after the default consent call.
- Review Admin to match policy. In GA4 Admin, I open Data collection. Google signals is gated by ad_personalization. If my stance is conservative, I leave signals off. If allowed, I enable signals and ensure the banner maps that toggle to ad_personalization. See the Impact of Consent.
- Understand the two ad-related consent types. ad_user_data controls features such as remarketing lists, granular user data for Ads integrations, and enhanced conversions uploads. ad_personalization controls personalized ads and Google signals. Many teams separate these so a user can permit measurement without personalized ads.
- Expect some behavior changes. Enhanced measurement continues, but with limited detail while analytics_storage is denied. Reports may show modeled data. That is normal.
- Keep tests clean. I exclude internal traffic so consent tests are not lost in filters. I use a separate test device and incognito.
Property-level switches are not a substitute for tag-level consent. GA4 settings control features. Consent Mode controls data flow per page view and per user choice. I keep both aligned. To keep naming consistent in documentation, I reference the Consent Mode v2 parameters ad_user_data and ad_personalization when creating internal playbooks.
Consent Mode v2 testing and debugging
Here is a reliable verification flow that maps to Google guidance and works well for B2B teams with tight release cycles.
1) Tag Assistant
- I open Tag Assistant and start a live session. I load a page without granting consent. I should see tags fired with consent denied and no cookies created. I accept on the banner, refresh, and confirm granted states. Reference: Verify Implementation.
2) GTM Preview
- In GTM Preview mode, I check the event timeline. I should see Consent Initialization, then the CMP update, then GA4 and Ads tags. I open Consent Overview to confirm each tag lists the correct required consents.
3) Network inspection
- In the browser’s developer tools, I filter for collect and gtag network calls. I look for gcs and gcd parameters. They encode consent states. Before consent, I should see denied states in those params and no cookies. How to open DevTools: browser’s console. For a quick console helper, run this JavaScript code.
4) Google Ads diagnostics
- In Google Ads, I open Tools and Settings > Conversions > Diagnostics. I check consent mode signals received and watch for a share of modeled conversions over time. Small changes at first are fine.
5) A/B testing consent states
- I run one test journey where I deny everything, and another where I grant all. I compare hits in Tag Assistant and GA4 DebugView.

Important notes about caching and optimization plugins
- I exclude CMP scripts, GTM, and consent snippets from defer, delay, minify, and concatenation. The execution order matters. See this caching and optimization guide.
- I do not cache the banner’s DOM state server-side. Each user needs a fresh rendering on first load.
- If I run a CDN, I bypass consent scripts from edge aggregation.
- On WordPress, I add consent and GTM scripts to exclusion lists in common performance plugins.
Common errors and fixes
- Duplicate Google tags causing double hits: I remove extra script includes. I keep one GA4 config and one Ads config per property.
- Wrong script order: Consent default must run first. Then load gtag.js. Then config calls. Then the update on banner action.
- Region scoping mistakes: Defaults applied worldwide by accident depress measurement in regions I did not intend. I use the region array or GTM conditions.
- CMP never fires updates: I check the CMP event hook. I ensure the gtag consent update runs on both Accept and Save choices, not only Accept all.
- Ads conversions not modeling: I confirm Google Ads Consent Mode v2 integration is active, the Conversion Linker is present, and Ads diagnostics show consent signals received.
FAQs
- Do I need a CMP, and is IAB TCF 2.2 mandatory?
If I serve Google Ads to users in the EEA or UK, a certified CMP that supports TCF 2.2 is required by Google policy. For analytics only, a CMP is still recommended so I capture valid consent records. See Set up your consent banner with a consent management platform or a content management system. - What is the difference between Basic and Advanced for GA4 and Ads performance?
Basic sends nothing until the user interacts, which reduces the data available for modeling. Advanced sends cookieless pings before the click and improves modeled accuracy for my site. - How do ad_user_data and ad_personalization affect remarketing and enhanced conversions?
ad_user_data controls user-level data used for remarketing lists and enhanced conversions. ad_personalization controls personalized ads and Google signals. Many teams permit the first and restrict the second. For details on URL passthrough and redaction, see Impact of Consent. - Can I run v2 with only gtag.js and no GTM?
Yes. I follow the exact script order and send a single consent update on the CMP callback. - Does Consent Mode v2 make my site compliant by itself?
No. It helps with measurement and Ads policy. Compliance requires a lawful basis, record keeping, and a proper banner or CMP. See Choosing your Consent Framework. - What if I only use GA4 and no Ads?
I still gain modeled conversions when users deny analytics cookies, which stabilizes reporting. - How do I limit Consent Mode to EEA and UK only?
I use the region parameter in the default call or trigger conditions in GTM based on geo detection. - How do I test that Google Ads recognizes my consent signals?
I use Ads Conversion diagnostics and Tag Assistant. I should see consent signals received and a share of modeled conversions after traffic accrues. - Will Consent Mode hurt conversion rates or data accuracy?
I may see fewer observed conversions when more users deny consent. Modeled conversions fill some gaps. Clear banners with honest language tend to maintain acceptance rates. - What about apps?
For apps measured with Firebase, I follow Google’s app guidance: Set up consent mode for apps. - Using Site Kit?
See How to Set Up Consent Mode v2 with Google Site Kit and Google Analytics.