Split architecture diagram comparing Partytown running third-party scripts in a browser web worker versus Cloudflare Zaraz executing them on the edge.

Partytown vs Cloudflare Zaraz: Relocate Third-Party Scripts or Remove Them

Partytown moves third-party scripts into a web worker. Cloudflare Zaraz removes them from the browser entirely. A comparison of both architectures, what each breaks in GA4, and when each one is the right call.

#cloudflare zaraz #partytown #performance #google analytics #ga4 #core web vitals #astro #cloudflare workers #consent management

In April 2024 someone opened an issue in the Partytown repository titled “GA4 sessions plummeted after migration of GTM to Partytown”. One developer in the thread reports a site that tracked 150,000 sessions a day before Partytown and 60,000 after. His fix, posted right there in the official tracker, was switching to Cloudflare Zaraz.

As of June 2026 that issue is still open. Two years is long enough to say the problem is not a bug waiting for a patch; it is a property of the architecture. And it captures the real shape of this comparison: both tools attack the same enemy, third-party scripts strangling the main thread, and both can quietly wreck your analytics on the way to a green Lighthouse score.

What Partytown and Cloudflare Zaraz actually do differently

The one-line difference: Partytown relocates script execution, Zaraz removes it. Partytown takes the same third-party JavaScript your page already loads and runs it in a web worker, behind a proxied copy of the DOM. The scripts still download, still parse, and still execute in the visitor’s browser; they just stop competing with your code for the main thread.

Zaraz takes the opposite route. Vendor logic runs as Managed Components inside Cloudflare Workers, on the edge, and the browser ships a single lightweight loader instead of the Meta pixel, the GA4 snippet, and whatever else marketing added last quarter. The third-party code never reaches the device.

Everything else in this comparison follows from that split: what breaks in GA4, how consent works, what each tool demands from your hosting, and which one survives a high-traffic production deploy. The decision is less about which is faster and more about which failure modes you can live with.

TL;DR

  • Partytown moves third-party JS into a web worker. The scripts still execute in the browser against a proxied DOM, so compatibility is per-script and never guaranteed.
  • Cloudflare Zaraz executes vendor logic at the edge via Managed Components. The browser gets one loader; the tracking payloads originate from Cloudflare’s network.
  • Partytown is not deprecated. It moved from Builder.io to QwikDev in January 2025 and shipped v0.14.0 in May 2026, but it has carried a beta label since 2021.
  • Both can break GA4. Partytown loses collect requests and engagement events (open issues). Zaraz forwards only three events by design and hands you the rest.
  • Consent is one-sided: Zaraz ships a CMP with Google Consent Mode v2 built in. Partytown has no consent story at all.
  • Not on Cloudflare? Partytown is still the right call. On Cloudflare, Zaraz starts free for 1M events a month.

Is Partytown deprecated? No, but the story is complicated

The deprecation rumor floats around developer forums, and it has a real event behind it. In January 2025 the project moved from Builder.io to the QwikDev organization, and the npm package changed from @builder.io/partytown to @qwik.dev/partytown. The old package froze at version 0.10.2 and never got a deprecation notice on npm.

That silent freeze is where the rumor comes from. Half the Partytown tutorials on the internet still point at @builder.io/partytown, so anyone following them installs a package that stopped receiving updates in 2024 and looks abandoned. The project itself is alive: v0.14.0 shipped in May 2026, and the official @astrojs/partytown integration already depends on the new package.

The more telling label is the one that never changed. The README has said the same thing since 2021: Partytown is still in beta and not guaranteed to work in every scenario. Five years in, with 13,000+ GitHub stars and production deployments everywhere, the maintainers still will not call it stable. That is not negligence; it is a precise description of the architecture, and the next section shows why.

How Partytown works: a proxied DOM in a web worker

Partytown’s trick is making third-party scripts believe they are on the main thread when they are not. You mark a script with type="text/partytown", and instead of executing it, the browser hands it to a web worker. The script still downloads, still parses, and still runs on the visitor’s device. It just runs in a thread that cannot block rendering.

The hard part is that web workers have no DOM access, and tracking scripts touch document, window, cookies, and element attributes constantly. Partytown solves this with a synchronous proxy: every DOM read from the worker becomes a blocking request to the main thread, served either through a service worker intercepting fake network calls or through Atomics and SharedArrayBuffer. The worker-side code gets a faithful, if slow, illusion of the page.

And it delivers on the headline metric. DebugBear’s guide to Partytown, updated in October 2025, cites a Next.js comparison where adding Google Tag Manager through Partytown took the Lighthouse Performance score from around 70 to around 99, with the main-thread warnings gone. For Lighthouse and Total Blocking Time, relocation works.

The fine print is the cost. DOM operations from the worker are deliberately throttled, and the faster Atomics mode requires crossOriginIsolated, which means serving your whole document with COOP and COEP headers; credentialless is not supported in Safari, and require-corp blocks every CDN image and script that lacks a crossorigin attribute.

Scripts without CORS headers need a manual reverse proxy via resolveUrl, and event.preventDefault() from the worker does nothing. The project’s own trade-offs page lists all of this and concludes that Partytown may not be the best fit for every script.

Each of those constraints is per-script and per-vendor. That is why Partytown ships as opt-in, and why it stays in beta: the architecture cannot promise that an arbitrary third-party script will behave behind a proxied DOM. Many do. The ones that matter most for revenue, analytics and ad pixels, are exactly the ones with the longest issue threads.

How Zaraz works: server-side tagging on Cloudflare’s edge

Zaraz is Cloudflare’s take on server-side tagging, and it starts from a different premise: the browser should not run vendor code at all. Each tool you add in the Zaraz dashboard runs as a Managed Component inside a Cloudflare Worker, at the edge, on the same network that already serves your site. The browser ships one small loader that batches events and sends them to your own domain.

When a pageview fires, the edge worker fans it out to GA4, Meta, or whatever is configured, server to server. The Meta pixel never downloads to the device. There is no proxied DOM because there is no third-party code looking for a DOM; vendors receive events over their server APIs instead of running JavaScript in the visitor’s tab.

flowchart TB
    subgraph PT["Partytown: relocate execution"]
        direction TB
        A["Main thread"] -->|"type=text/partytown"| W["Web worker"]
        W -->|"proxied DOM calls (throttled)"| A
        W -->|"requests to vendor domains"| V1["googletagmanager.com<br/>connect.facebook.net"]
    end
    subgraph ZR["Zaraz: remove execution"]
        direction TB
        B["Main thread"] -->|"one loader, first-party events"| E["Cloudflare edge worker"]
        E -->|"server-to-server fan-out"| V2["GA4 / Meta / Ads APIs"]
    end
    V1 ~~~ B

This sidesteps Partytown’s entire problem class. Nothing needs CORS workarounds, nothing fights a throttled DOM proxy, and ad blockers that filter googletagmanager.com requests never see one, because tracking calls originate from your domain and Cloudflare’s network. The browser-side cost stays constant whether you run two tools or twenty.

The constraint is the flip side of the same design: Zaraz is a Cloudflare product. It expects your DNS proxied through Cloudflare (a setup for non-proxied domains exists, with caveats), and the tool catalog is whatever has a Managed Component. Pricing starts at 1 million events per month free on every plan, which covers most sites this article’s readers run.

One more difference worth naming: with Zaraz, the parts of tracking that need page context (scroll depth, click listeners) are dashboard-configured triggers, not vendor scripts. The platform owns the DOM listeners and keeps them minimal, instead of proxying a vendor’s assumptions about a main thread it no longer lives on.

Both break GA4, in opposite ways

You will run into the claim that analytics through Partytown works with no data loss. It circulates in old forum threads, and AI assistants repeat it with confidence. The project’s own issue tracker disagrees, at length, and the difference between the two tools is not whether GA4 breaks but how.

Partytown breaks GA4 nondeterministically. The flagship thread is issue #583: GTM moved into the worker, collect requests silently stop being sent, and a site drops from 150,000 tracked sessions a day to 60,000. The workarounds scattered through the thread tell the story: set keepalive: false on beacon requests, define window.global = document before GTM loads, or watch the dataLayer get silently swapped mid-initialization. Issue #603 adds user_engagement and scroll events that never fire; both issues remain open as of June 2026.

The pattern across these reports is the worst kind of failure: partial. Pageviews arrive, so dashboards look alive, while sessions, engagement, and conversions quietly undercount. Nothing errors. You find out when a marketing report disagrees with reality, weeks later.

Zaraz breaks GA4 deterministically. Cloudflare documents in its FAQ that Zaraz auto-forwards only page_view, session_start, and first_visit, and that everything GA4 calls an Enhanced Measurement is yours to build. Engaged sessions read zero until you wire a user_engagement event yourself, which is exactly the failure I documented and fixed in the Zaraz GA4 engaged sessions guide.

That difference decides more than it seems. A documented gap has a documented fix: one component, written once, stable since. An undocumented race between a proxied DOM and a 300 KB tag manager has a two-year-old issue thread and a collection of workarounds that help some sites and not others. If analytics drives ad spend, deterministic breakage is the one you want.

Ad blockers: only one of these tools changes the math

There is a second source of data loss that has nothing to do with either tool breaking: ad blockers and tracking protection. uBlock Origin, Brave, and Safari’s ITP filter tracking requests by domain and path, and for developer-heavy audiences the blocked share of traffic runs far above the general average. Whatever the blockers eat never reaches GA4 at all.

Partytown does nothing about this, by design. The GTM script still downloads from googletagmanager.com and the hits still fly to google-analytics.com; running the code in a worker changes which thread executes it, not which domains appear in the network log. Filter lists block by domain, so the worker’s requests die exactly like main-thread ones. This is not a flaw in Partytown, it is simply outside its scope.

Zaraz changes the surface area. Vendor domains disappear from the browser entirely: events go to your own hostname, and the fan-out to Google or Meta happens server-side from Cloudflare’s network, where no browser extension exists. The blocklist has nothing third-party to match against.

The necessary caveat is that the defaults are a known target. Zaraz’s standard /cdn-cgi/zaraz/ paths are listed in privacy filter lists, and uBlock Origin blocks them out of the box. Cloudflare’s documented answer is custom endpoints: you can serve the loader and events from any pathname you choose, like /assets/app.js, which a generic filter list cannot distinguish from your application code.

This is a two-minute change in the dashboard, and it is how edgekits.dev runs. Open this site’s network tab and you will find no /cdn-cgi/zaraz/ requests, just a script and a collect call on paths that belong to the site.

Browser devtools network tab on edgekits.dev showing the Cloudflare Zaraz loader served as a first-party view.js script and tracking events sent to a renamed collect endpoint, with no default cdn-cgi zaraz paths for ad blockers to match.

One boundary worth stating plainly: this is about data quality, not consent evasion. Events still flow through Zaraz’s consent gate and Google Consent Mode v2, so a visitor who declines tracking stays declined. The point is that a visitor who consented should actually show up in your reports, even with an ad blocker installed. Which brings us to consent itself.

Everywhere else in this article the two tools trade punches. On consent management there is no exchange, because Partytown does not have a consent story and was never meant to. It is a script-execution library: deciding whether a script should run based on a GDPR choice is your job, done with a separate CMP, before Partytown ever sees the script.

In practice that means stacking tools. A typical Partytown site runs a third-party CMP (Cookiebot, OneTrust, Usercentrics) on the main thread, which gates the type="text/partytown" scripts, which then execute in the worker. The CMP itself is render-blocking third-party JavaScript, often the heaviest on the page, and it cannot go into the worker because it is exactly the kind of UI-building, preventDefault-dependent script the trade-offs page warns about. You adopt Partytown to get third-party code off the main thread and the compliance layer stays there anyway.

Zaraz ships the whole layer. Consent Management is built in: each tool is assigned a purpose, the consent state gates which Managed Components fire, and Google Consent Mode v2 signals flow to Google automatically. A declined visitor produces a cookieless ping instead of a full hit, which keeps modeled conversions alive without storing anything on the device.

The banner itself can be Zaraz’s built-in modal, or your own UI talking to the Consent API. On edgekits.dev it is a custom server-rendered component that ships zero JavaScript to returning visitors, built in the zero-JS Zaraz consent banner guide. Either way the gate, the signals, and the tools live in one system instead of three.

If your site serves EU traffic and runs anything beyond first-party analytics, this section is probably the whole decision. The performance argument for Partytown weakens considerably when a heavyweight CMP stays on the main thread; the consent argument for Zaraz does not weaken in the other direction.

When Partytown is still the right call

None of the above makes Partytown the wrong tool, it makes it a specific one. There are setups where it is the better answer, and they are easy to describe.

The clearest case is hosting. Zaraz requires Cloudflare; Partytown requires a folder of static files. If the site lives on Netlify, Vercel, GitHub Pages, or a client’s locked-down WordPress host, and moving DNS to Cloudflare is not on the table, Partytown is the only one of the two you can actually deploy. That is not a tiebreaker, it is the whole decision.

The second case is scope. A content site with one event-driven analytics script, no consent obligations, and no ad spend riding on the numbers gets most of Partytown’s upside with little exposure to its failure modes. The DebugBear-cited Lighthouse jump is real, and on a site where a session undercount costs nothing, the trade is fine.

The third case is vendor fit. Scripts that only listen to events and post data in the background are Partytown’s sweet spot, and the project says so itself. What does not belong in the worker: anything that builds UI, A/B testing tools that rewrite the page before paint, session recorders, and cookie banners. If your stack is mostly the first kind, Partytown earns its place.

What changed my own default is the combination this article keeps circling: Cloudflare hosting, EU traffic, and analytics that feed decisions. Hit all three and the relocation model starts costing more than it saves. Miss one and Partytown remains a perfectly reasonable tool that ships in five minutes.

The maintenance question both projects need to answer

Neither tool gets a clean bill of health here, and the failure modes rhyme with the architectures.

Partytown ships releases, slowly. After the QwikDev handover, v0.13.2 arrived in April 2026 and v0.14.0 in May 2026, with months of quiet between versions and changes mostly at patch level. The beta label is now in its fifth year, and the GA4 issue threads from 2024 remain open. The project is alive; the hard problems are not getting solved, because they may not be solvable inside a proxied DOM.

Zaraz is generally available and carries no beta disclaimer, but its public changelog has not recorded a feature since February 2025. The platform runs reliably at Cloudflare’s scale, and nothing suggests deprecation, but the GA4 forwarding gap documented in its FAQ has sat unchanged just as long. Pick Zaraz and you are betting on a stable platform in maintenance mode, plus your own code for the gaps.

That symmetry is the closing thought. Partytown is an ingenious workaround for vendor scripts that were never designed to leave the main thread, and the open issues are the cost of the workaround. Zaraz is a cleaner architecture with a thinner roadmap, and the gaps are the cost of the cleanliness. For a site on Cloudflare with revenue attached to its analytics, I will take the architecture with documented gaps over the workaround with undocumented ones.

Planning a third-party script migration and want help with the analytics layer? gary@edgekits.dev

Frequently Asked Questions

Is Partytown deprecated?

No. The rumor comes from a January 2025 organizational move: the project transferred from Builder.io to QwikDev, and the npm package changed from @builder.io/partytown to @qwik.dev/partytown. The old package froze at version 0.10.2 without a deprecation notice, so tutorials pointing at it make the project look abandoned. The repository is active, with v0.13.2 released in April 2026 and v0.14.0 in May 2026, and the official @astrojs/partytown integration already depends on the new package. The more meaningful status marker is the beta label: the README has stated since 2021 that Partytown is not guaranteed to work in every scenario, because a proxied DOM cannot promise compatibility with arbitrary third-party scripts.

What is the difference between Partytown and Cloudflare Zaraz?

Partytown relocates third-party script execution; Cloudflare Zaraz removes it. With Partytown, vendor JavaScript still downloads, parses, and executes in the browser, but inside a web worker that talks to the page through a synchronous DOM proxy, so it cannot block the main thread. With Zaraz, vendor logic runs as Managed Components inside Cloudflare Workers at the edge: the browser ships one lightweight loader, and events fan out to GA4, Meta, or Google Ads server to server. The practical consequences follow from that split. Partytown works on any hosting but inherits per-script compatibility risk and does nothing about ad blockers. Zaraz requires Cloudflare, starts free for 1 million events per month, and removes vendor domains from the browser entirely.

Does Partytown lose Google Analytics data?

It can, and the failure is partial rather than total, which makes it dangerous. Issue #583 in the Partytown repository, open since April 2024, documents GA4 sessions dropping after GTM moved into the web worker, including one site that fell from 150,000 tracked sessions a day to 60,000 because collect requests silently stopped being sent. Issue #603 reports user_engagement and scroll events that never fire. Known workarounds include setting keepalive: false on beacon requests and defining window.global = document before GTM initializes, but they help some sites and not others. Pageviews usually keep arriving, so dashboards look healthy while sessions, engagement, and conversions undercount. Claims that Partytown tracking works with no data loss predate these issue threads and should be treated as outdated.

Does Cloudflare Zaraz bypass ad blockers?

Partially, and only after configuration. Zaraz removes vendor domains like googletagmanager.com from the browser, so domain-based filter rules have nothing to match; tracking events go to your own hostname and fan out to vendors from the edge. However, the default /cdn-cgi/zaraz/ endpoint paths are listed in privacy filter lists, and uBlock Origin blocks them out of the box. The documented fix is the custom endpoints setting, which serves the Zaraz loader and event calls from any pathname you choose, making them indistinguishable from first-party application code to a generic blocklist. This is a data-quality measure, not consent evasion: events still pass through the Zaraz consent gate and Google Consent Mode v2, so declined visitors stay declined regardless of endpoint paths.

Does Zaraz require Cloudflare and what does it cost?

Zaraz is a Cloudflare product and expects your DNS proxied through Cloudflare; a documented setup for non-proxied domains exists but with caveats. Pricing starts at 1 million events per month free on every Cloudflare plan, including the Free tier, with every feature unlocked, and paid usage beyond that. For comparison, Partytown is an MIT-licensed library that runs anywhere static files can be served and costs nothing at any scale. The cost question therefore usually reduces to architecture: if the site is already behind Cloudflare, Zaraz adds server-side tagging without new vendors or subscriptions, and replaces paid CMP subscriptions in the same move. If the site cannot move to Cloudflare, Zaraz is simply unavailable and the comparison ends there.

When should I use Partytown instead of Zaraz?

Three cases. First, hosting: if the site runs on Netlify, Vercel, GitHub Pages, or any host where moving DNS to Cloudflare is not an option, Partytown is the only deployable choice of the two. Second, scope: a content site with one event-driven analytics script, no EU consent obligations, and no ad budget depending on the numbers captures the Lighthouse improvement with little exposure to the failure modes. Third, vendor fit: scripts that only listen to events and post data in the background are the documented sweet spot. Partytown is the wrong place for UI-building scripts, A/B testing tools that rewrite the page before paint, session recorders, and cookie banners, all of which depend on synchronous DOM access the worker cannot provide.

Can Partytown handle cookie consent banners and CMPs?

No. Consent management platforms are exactly the kind of script the Partytown trade-offs documentation warns against: they build UI, intercept clicks, depend on event.preventDefault, and must run before other scripts to gate them, none of which works from a web worker with throttled, asynchronous DOM access. A Partytown site therefore stacks tools: a third-party CMP runs on the main thread, gates the text/partytown scripts, and remains the heaviest render-blocking JavaScript on the page. This undercuts the performance argument for adopting Partytown in the first place. Cloudflare Zaraz ships the consent layer inside the platform: purposes gate Managed Components, Google Consent Mode v2 signals flow automatically, and the banner can be the built-in modal or a custom UI talking to the Consent API.

Why does GA4 show zero engaged sessions after switching to Zaraz?

Because Zaraz auto-forwards only three events to GA4: page_view, session_start, and first_visit. The Cloudflare FAQ states this directly and notes it is not a bug. Everything GA4 calls an Enhanced Measurement, including the user_engagement event that carries engagement_time_msec and marks sessions as engaged past the 10-second threshold, must be built with custom triggers and actions. Until you emit user_engagement yourself through zaraz.track(), single-page visits of any length look like bounces and engaged sessions read zero. The fix is deterministic: one visibility-aware, activity-aware component that measures real active time and flushes it to GA4. That is a documented gap with a documented fix, in contrast to Partytown, where engagement events are lost nondeterministically with no stable resolution.

We use cookies to analyze site traffic and improve your experience. By clicking "Accept All", you consent to our use of analytical tracking.