Geo-Distributed A/B Testing with CDN Edge Workers
This article outlines how modern engineering teams configure CDN edge workers to conduct geo-distributed A/B testing at scale. By moving experimentation logic from the origin server or client-side JavaScript to edge compute nodes, teams eliminate the visual flicker typical of client-side tools and prevent the latency penalties of origin-based routing. The following sections detail the complete workflow, from extracting edge geolocation metadata and assigning deterministic variants to manipulating requests and streaming telemetry.
1. Intercepting Requests at the Edge
Edge workers (such as Cloudflare Workers, AWS CloudFront Functions,
or Fastly Compute) execute serverless logic inside Points of Presence
(PoPs) closest to the user. Teams configure these workers to intercept
incoming GET requests before the CDN cache lookup or origin
fetch occurs. This allows the edge worker to inspect headers, cookies,
and network-level metadata to make routing decisions in single-digit
milliseconds.
2. Reading Geolocation Metadata
CDNs automatically enrich incoming requests with geographic data derived from the client's IP address. Teams extract these properties directly from the runtime context or platform-specific headers:
- Cloudflare:
request.cf.country,request.cf.region, orrequest.cf.city - AWS CloudFront: Headers such as
CloudFront-Viewer-Country,CloudFront-Viewer-Country-Region, andCloudFront-Viewer-Postal-Code - Fastly: Functions like
client.geo.country_codeandclient.geo.city
By reading these values, teams establish audience targeting rules. For example, a test might run exclusively in the United Kingdom or split variants based on regional latency boundaries.
3. Implementing Variant Assignment and Persistence
To ensure a consistent user experience, edge workers must assign users to a variant (control vs. experiment) and persist that assignment across future visits.
Cookie Inspection: The worker checks the
Cookieheader for an existing test identifier (e.g.,ab_test_geo=B). If found, the user continues to receive that assigned variant.Deterministic Hashing: If no cookie exists, the worker generates an assignment. Rather than purely random selection, teams often hash a unique user ID (or a newly generated UUID) combined with the experiment name using an algorithm like MurmurHash or SHA-256:
bucket = hash(userID + experimentID) % 100This guarantees uniform distribution according to the team's defined allocation weights (e.g., a 50/50 split).
Setting Persistence: The worker appends a
Set-Cookieheader to the outgoing response, locking the client to that variant for the duration of the test.
4. Modifying Routing and HTML at the Edge
Once the variant is determined, teams serve the appropriate content using one of two primary patterns:
- Subrequest Rewriting: The edge worker alters the
upstream origin path or query parameter. For variant B, the worker
fetches
/experiments/v2/index.htmlfrom the origin while the user's browser URL remains/. This completely avoids external redirects (HTTP 301/302) and eliminates page flicker. - In-Flight HTML Rewriting: For localized content
modifications (such as changing a headline, currency, or CTA button
based on region), teams use an edge-native HTML parser (e.g.,
Cloudflare’s
HTMLRewriter). The worker streams the original HTML from the origin, modifies specific DOM elements on the fly, and streams the modified response to the client with negligible overhead.
5. Logging and Analytics at the Edge
A/B testing requires strict tracking of impressions and conversions. Because the routing happens at the edge, client-side analytics might miss initial variant exposures or experience ad-blocker drop-offs.
Teams solve this by decoupling analytics logging from the response path:
- Asynchronous Contexts: Workers use execution
lifecycle hooks (such as
event.waitUntil()or background tasks) to dispatch impression payloads to analytics endpoints, data warehouses, or edge key-value stores. - Log Streaming: Alternatively, workers annotate
custom request headers (e.g.,
X-Experiment-Variant: B) that are captured by CDN real-time log streaming systems (like Datadog, BigQuery, or Amazon Kinesis), avoiding extra network calls during request execution.