Edge A/B Testing with Cloudflare Workers: Split Traffic Without Changing Origin
Learn how to run edge‑based A/B tests with Cloudflare Workers, see a concrete Worker example, and understand the CPU‑time and caching limits.
22 Aug 2026, 12:53 UTC

Problem
Product teams often need to test UI changes quickly but lack a low‑latency way to split traffic without touching the origin application or deploying new code.
Worker basics
A Cloudflare Worker is a JavaScript service that runs on Cloudflare’s edge network for every incoming HTTP request. The worker receives a Request object, can inspect headers, cookies, or the URL, and then decides how to respond.
Variant delivery
Once a variant is chosen, the worker can return a different HTML snippet, rewrite links, or inject a script. To keep the user seeing the same version on subsequent requests, the worker sets a client‑side cookie (e.g., ab_test) that it reads on the next request.
Worked example: 50/50 split
addEventListener('fetch', event => {
event.respondWith(handleRequest(event.request))
})
async function handleRequest(request) {
// read existing experiment cookie
const cookie = request.headers.get('Cookie') || ''
const match = cookie.match(/ab_test=([^;]+)/)
let variant = match ? match[1] : null
if (!variant) {
// 50/50 split
variant = Math.random() < 0.5 ? 'A' : 'B'
}
// fetch the variant HTML from a KV namespace bound as VARIANTS_KV
const html = await VARIANTS_KV.get(`variant-${variant}`)
if (!html) {
return new Response('Variant not found', {status: 404})
}
const resp = new Response(html, {headers: {'Content-Type': 'text/html'}})
// persist the choice for future requests
resp.headers.append('Set-Cookie', `ab_test=${variant}; Path=/; Max-Age=86400`)
return resp
}
Trade‑off and limitation
- Free‑tier Workers are limited to 50 ms CPU time per request; complex variant logic or large KV look‑ups can exceed this and trigger a "CPU time exceeded" error.
- Workers cannot reliably read or modify
Set‑Cookieheaders sent by the origin, so experiment state must be stored client‑side (cookie or localStorage). - If the origin or Cloudflare caches responses aggressively, the cache key must include the variant (e.g., via a query string or a custom cache‑key header) otherwise users may see a cached version of the wrong variant.
Actionable closing
- Create a KV namespace (e.g.,
variant‑store) and upload two files:variant-A.htmlandvariant-B.html. - Bind the namespace to your Worker script as
VARIANTS_KV. - Deploy the Worker to a test sub‑domain (e.g.,
experiments.example.com) usingwrangler publish(requires an API token withAccount.Workers Scripts Editpermission). - Verify in browser devtools that the response HTML matches the expected variant and that the
ab_testcookie is set. - Check Cloudflare Workers Logs or Traffic Analytics to confirm roughly equal request counts over a few minutes.
- Run a lightweight load test (e.g.,
k6 run script.js) and ensure the average CPU time reported in Workers metrics stays below ~40 ms, leaving headroom for spikes. - If CPU time approaches the limit, simplify the logic or move heavy look‑ups to the KV namespace’s bulk API.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.