Running third-party scripts where they can't hurt performance
Third-party JavaScript powers much of the modern web: analytics, chatbots, conversion pixels and widgets all rely on code hosted outside the site owner's direct control. These tools usually work by giving you a small snippet to paste into your HTML, which then fetches additional scripts from remote servers. The result is a chain of requests over which you have little visibility or authority.
That lack of control has real consequences. A compromised third-party script can steal data, mine cryptocurrency or log keystrokes without the site owner knowing. Even without malicious intent, many vendors collect more than they need. User emails often end up in third-party analytics purely because they appear in a URL such as a password-reset page, creating compliance risk under GDPR and CCPA.
What actually happens in the browser
Consider Google Analytics, the most widely deployed third-party script. The standard snippet creates a new <script> element pointing to https://www.google-analytics.com/analytics.js and appends it to the DOM. The browser fetches and executes that file, which may in turn request more scripts. Notably, at this point no analytics data has been captured at all.
Data collection only starts with the final line of the snippet: ga('send', 'pageview');. That call invokes a function in analytics.js that gathers browser type, screen resolution, language and similar details, constructs a URL with that information and sends a request. Every subsequent user event triggers another such request. Most tools follow the same pattern, loading multiple resources and making it impossible to predict their full network behavior without testing. Visualizing a site's requests typically shows many third-party circles surrounding the site's own resources — with sub-requests and redirect chains creating significant extra network traffic.
Moving execution out of the browser
Zaraz takes a different approach: third-party code runs outside the browser, on the edge, while still receiving the information it needs and interacting with the DOM when required. This shift brings several advantages.
- Faster page loads: The browser no longer downloads, parses and executes third-party scripts, so rendering and interactivity don't compete with or get blocked by external code.
- Data control: Running tools server-side means full visibility into what data is being sent. Zaraz can flag or filter attempts to collect Personally Identifiable Information, after masking is available.
- Security scanning: With code execution moved out of the browser and scanned centrally, Zaraz can continuously verify that scripts haven't been tampered with and only do what they're supposed to do. Integration with Cloudflare Page Shield is planned to automate this.
With a conventional tag manager, the browser loads the manager, evaluates trigger rules and appends third-party script tags to the DOM. Those scripts come from unknown origins, can block interactivity until they finish executing, and are free to collect and transmit whatever they can access. The edge-based approach eliminates most of that browser-side activity.
Why Cloudflare Workers fit the requirements
Building Zaraz required an infrastructure choice with significant consequences. Traditional tag managers have no server-side component — they render a static JavaScript file hosted on a CDN. Zaraz needed a server-side component that could generate JavaScript dynamically per request while performing as fast as a CDN, to avoid slowing sites down.
The evaluation criteria for a serverless platform were specific:
- Run JavaScript: Since third-party tools are JavaScript-based, porting them would be simplest in a JavaScript environment.
- Secure: Sensitive data processing meant data shouldn't persist on servers after responding.
- Fully programmable: Standard CDN rules for headers and redirects weren't enough — generating JavaScript on the fly required full response control and support for external libraries.
- Fast and global: Early users spanned the US, Europe, India and Israel, demanding CDN-like response times everywhere.
Initial plans involved Docker containers with custom HTTP servers distributed globally. A colleague from Y Combinator suggested evaluating Cloudflare Workers. The initial hesitation was that Workers doesn't behave like Node.js, which seemed limiting. The original architecture paired Workers request handling with AWS Lambda for heavy processing.
A simple test changed that view: a Worker serving dynamically generated browser-side JavaScript responded in under 10 milliseconds. That proved the platform could serve a Worker as if it were a regular JavaScript file referenced via <script src="path/to/worker.js">.
Workers met every requirement. It runs the same V8 engine as browsers, keeping the environment consistent when porting tools. Serverless, stateless execution reassured customers that personal data couldn't be saved even accidentally. The webpack and Wrangler integration supported full applications with modules and dependencies. The Lambda component became redundant and was removed entirely.
Scaling on the platform
As the Workers platform matured, Zaraz adopted its higher-level services. Workers KV stores user configurations, and Durable Objects coordinate between Workers. The main Worker contains server-side implementations of over 50 popular third-party tools, replacing hundreds of thousands of lines of JavaScript that otherwise run in browsers. An SDK now lets third-party vendors build support for their own tools directly, working in an environment that is secure, private and fast — for the first time giving them an alternative to running unmanaged code in end users' browsers.
How Zaraz Runs Third-Party Code
Most third-party tools follow the same pattern: they grab data from the browser—screen resolution, URL, page title, cookies—and send it to their own server. That’s fine for one tool, but a site with dozens of them ends up with dozens of requests and large amounts of repetitive JavaScript. Zaraz takes a different approach. Each tool exposes a run function. When Zaraz decides a tool should load, it executes that function in a Cloudflare Worker, not in the browser.
run({system, utils}) {
// The `system` object includes information about the current page, browser, and more
const { device, page, cookies } = system
// The `utils` are a set of functions we found useful across multiple tools
const { getCookieString, waitUntil } = utils
// Get the existing cookie content, or create a new UUID instead
const cookieName = 'visitor-identifier'
const sessionCookie = cookies[cookieName] || crypto.randomUUID()
// Build the payload
const payload = {
session: sessionCookie,
ip: device.ip,
resolution: device.resolution,
ua: device.userAgent,
url: page.url.href,
title: page.title,
}
// Construct the URL
const baseURL = 'https://example.com/collect?'
const params = new URLSearchParams(payload)
const finalURL = baseURL + params
// Send a request to the third-party server from the edge
waitUntil(fetch(finalURL))
// Save or update the cookie in the browser
return getCookieString(cookieName, sessionCookie)
}
This shift has a major effect on performance. Previously, 10x more tools meant 10x more browser requests and 10x more JavaScript to parse and execute. Much of that code was redundant—nearly every tool ships its own cookie parser. It also meant trusting many more external origins. With tools running at the edge, the browser load stays flat no matter how many tools are added.
The run function has access to the full Workers runtime. For example, a tool can check for a visitor-identifier cookie; if it’s missing, it can generate a UUID via crypto.randomUUID(). It can gather user agent, URL, page title, screen resolution, client IP, and cookie data, build the request URL, and send the data using waitUntil. Zaraz’s fetch wrapper adds automatic logging, data loss prevention, and retries.
What the run function returns is handed to the browser as JavaScript. In the case of the cookie example, the return value is something like document.cookie = 'visitor-identifier=5006e6fa-7ce6-45ef-8724-c846f1953369; Path=/; Max-age=31536000';. That sets a first-party cookie so subsequent visits reuse the UUID rather than generating a fresh one.
Isolating each tool in its own run function keeps them independent while still giving them the browser context and Workers capabilities they need. Zaraz has used this pattern for integrations with more than 50 tools and is inviting vendors to write their own.
Event Handling Without Browser Overhead
Some tools need to react to user behavior mid-visit, like firing a conversion pixel after a form submission. Since tool code no longer runs in the browser, Zaraz provides zaraz.track() to trigger tools programmatically with optional additional data.
document.getElementById("credit-card-form").addEventListener("submit", () => {
zaraz.track("card-submission", {
value: document.getElementById("total").innerHTML,
transaction: "X-98765",
});
});
In the example above, Zaraz receives a trigger named card-submission along with a transaction value read from an element with ID total and a hardcoded transaction code. On the edge, Zaraz checks which tools are subscribed to that trigger and calls them with the supplied data.
This differs from traditional tag managers. GTM’s dataLayer.push does something similar but evaluates everything client-side. Heavy GTM usage can make its own script the largest asset on a page. Each dataLayer.push event triggers repeated browser-side code evaluation, and matching tools can load yet more external scripts. Since these events often coincide with user interactions, the main thread gets tied up and the site feels unresponsive. With Zaraz, that evaluation happens only at the edge.

Triggers don’t require coding. The Zaraz dashboard includes predefined templates for click listeners, scroll events, and other common behaviors that can be attached to page elements without touching site code. Combining zaraz.track() with custom tools effectively becomes a one-line integration of Workers into a webpage: any backend code can run at the right moment with the right parameters.
The Move to Cloudflare
Early Zaraz customers often chose Cloudflare for their infrastructure, and some were already using Workers. Joining Cloudflare made it possible to inline parts of the code directly in the page and reduce network requests further. It also eliminated the DNS lookup for Zaraz’s own script by proxying it through customers’ domains via Workers.
The founding goal—cutting third-party bloat to make the web faster, more private, and more secure—has stayed constant since the Winter 2020 Y Combinator batch. Cloudflare shared that vision, and the acquisition lets Zaraz scale to millions of sites while reducing both load times and carbon emissions. The service is available as a free beta through the Cloudflare dashboard, with an enterprise waitlist for custom requirements.



