This question usually arrives disguised. What the client asks is "should we use Google Tag Manager or put the code in the site?" What they mean is "who should be able to change what our site sends to third parties, and how fast?" Answer that second question and the first one mostly answers itself.
What GTM actually is
Google Tag Manager is a container of JavaScript that your site loads once, after which marketers can inject, modify, and remove tags through a web interface without a developer or a deploy. That is its entire value and its entire risk in one sentence.
The value: a new ad platform pixel goes live in an hour instead of waiting three weeks for a release window. The risk: your container is production code that ships outside your code review, your testing, and usually your awareness. Every person with publish rights can change what runs on your checkout page this afternoon.
When GTM is the right call
- Marketing tags that come and go: ad platform pixels, conversion tags, affiliate snippets. Their churn rate is exactly what GTM was built for.
- Analytics event mapping. Site pushes to the dataLayer, GTM maps dataLayer to GA4 and friends. The contract stays in code; the tool wiring stays flexible.
- Consent orchestration. One place where consent state gates every marketing tag beats fifteen hand-rolled conditionals scattered through templates.
- Teams where marketing iterates weekly and engineering releases monthly. The speed mismatch is real, and GTM absorbs it.
When hardcoding is the right call
- Tracking your product depends on. If churn models, personalization, or billing-adjacent logic consume the events, they belong in the codebase with tests, not in a marketing container someone can edit on a Friday.
- Environments where the container is a liability: payment pages with strict Content Security Policy requirements, apps under heavy compliance constraints, anywhere legal needs to sign off on exactly what runs.
- Sites with no one to govern the container. GTM without an owner becomes a tag graveyard; sixty tags, twelve still useful, nobody willing to delete anything. If nobody will own it, fewer moving parts is the safer architecture.
- The one-tool site. A brochure site running only GA4 can load it directly via gtag and skip a whole layer of indirection.
The hybrid most mature setups converge on
In practice the good setups I see are not either-or. They split by change frequency and blast radius:
- The dataLayer contract lives in code. Developers own event pushes, reviewed and tested like any feature, because they are one.
- Tool wiring lives in GTM. Which platforms consume which events is marketing configuration, and it changes too often to deserve a deploy each time.
- Consent gating lives in one place, in GTM, applied to every marketing tag with no exceptions.
- Publish rights are scarce. Two or three people, versioned workspaces, and a habit of naming versions so the container has a history someone can read.
This gets you developer-grade stability where stability matters and marketing-grade speed where speed matters.
The failure mode of each, so you recognize yours
GTM's failure mode is entropy: unreviewed changes pile up until nobody can say what the container does, and the answer to "why did conversions double-count in March" is a shrug. Hardcoding's failure mode is starvation: every measurement request enters the engineering backlog behind features, so marketing quietly installs plugins and pixels around the process, and you end up with GTM anyway, just unofficially and worse.
If either of those paragraphs described your setup, the fix is rarely switching architectures. It is assigning an owner and writing down the contract. The architecture question is downstream of the governance question, which is why an audit of what actually fires today, mapped against who can change it, is where I start every tracking engagement. Verify first, then decide; the procedure is in how to check if your GA4 tracking actually works.