Edge Support
Learn how to configure the VWO FE JavaScript SDK for edge computing environments like Cloudflare Workers, Vercel Edge Functions, and AWS Lambda@Edge.
Overview
Modern edge platforms such as Cloudflare Workers, Vercel Edge Functions, and AWS Edge runtimes are optimized for low-latency, short-lived execution. While these environments provide excellent performance, they introduce unique challenges for SDK initialization and configuration management.
The VWO Feature Experimentation (FE) JavaScript SDK is fully compatible with edge environments. However, to achieve optimal performance and avoid unnecessary network calls, settings management must be handled differently than in traditional long-running servers.
Supported edge platforms include:
- Cloudflare Workers
- Vercel Edge Functions
- AWS Lambda@Edge
- Netlify Edge Functions
- Deno Deploy
- Fastly Compute@Edge
- and other similar edge environments
This document explains:
- Why default SDK initialization can be inefficient on edge
- How to fetch, cache, and reuse settings
- How to use explicit settings injection
- How to leverage the getSettings / setSettings storage connector APIs
- Recommended patterns for enterprise-scale deployments
For further details on the VWO FE JavaScript SDK, including specific configuration examples and advanced usage, refer to the VWO JavaScript SDK Documentation.
Default SDK Initialization (Not Recommended for Edge)
By default, the SDK fetches settings during initialization:
await VWO.init({
sdkKey: 'SDK_KEY',
accountId: 'ACCOUNT_ID'
});What Happens Internally
- SDK makes a network request to VWO servers
- Settings are fetched on every worker execution
- No reuse unless the runtime keeps the worker warm
Impact
- Redundant network calls
- Increased tail latency
- Inefficient for high-traffic edge workloads
Why Edge Environments Need Special Handling
Edge platforms introduce several behavioral constraints that impact any SDK performing remote calls (like tracking events):
- Stateless, Ephemeral Execution:
- Each invocation starts from a clean slate.
- In-memory variables may not persist.
- Persistence must rely on external storage (KV, Redis, etc.).
- Any pending asynchronous operations (e.g., tracking calls) can be terminated early if not awaited properly.
- Strict Execution Time Budgets:
- Many edge runtimes terminate execution immediately after returning a response, unless you explicitly signal that work is still pending.
- Cold starts are common
- Non-blocking HTTP Requests:
- All tracking calls are asynchronous and risk being dropped if the runtime ends the execution loop early.
Therefore, edge runtimes must explicitly flush tracking events before your function exits.
SDK Configuration for Edge Environments
Use the edgeConfig option when initializing the VWO SDK inside any edge runtime.
Parameter: edgeConfig
The edgeConfig option should only be used in serverless/edge environments (e.g., Cloudflare Workers, Vercel Edge Functions, AWS Lambda@Edge).
| Parameter | Description | Type | Default | Recommended Value in Edge |
|---|---|---|---|---|
| shouldWaitForTrackingCalls | Ensures SDK waits for async tracking operations | Boolean | true | true |
Why It Matters
With edgeConfig, core methods like getFlag, trackEvent, and setAttribute resolve quickly, while the actual tracking calls are deferred and handled when you call flushEvents.
Important Note
When using
edgeConfig, you must callawait flushEvents()at the end of your code flow to send tracking events to VWO for reporting purposes.
Essential Rule for Edge Environments
Always call vwoClient.flushEvents() before your function exits.
If events are not flushed, they may be dropped entirely.
Edge platforms provide different mechanisms to wait for async operations:
- Cloudflare Workers:
ctx.waitUntil(vwoClient.flushEvents) - Vercel Edge / Fastly:
waitUntil(vwoClient.flushEvents) - Other platforms: standard
await vwoClient.flushEvents()
Quick Start Configuration
Looking for platform-specific setup instructions?
Cloudflare Workers
Jump to Cloudflare Workers specific configuration and examples
Vercel Edge Functions
Jump to Vercel Edge Functions specific configuration and examples
Jump to Other Edge Environments specific configuration and examples
Example Configuration
Here's how you can configure the SDK to work properly in an edge environment:
const { init } = require('vwo-fme-node-sdk');
// Initialize VWO client with Edge environment support
async function main() {
const vwoClient = await init({
accountId: '123456',
sdkKey: '32-alpha-numeric-sdk-key',
// Edge configuration for serverless environments
edgeConfig: {
shouldWaitForTrackingCalls: true
}
});
const userContext = { id: 'unique_user_id' };
// Check if feature is enabled for the user
const flag = await vwoClient.getFlag('feature_key', userContext);
if (flag.isEnabled()) {
console.log('Feature is enabled!');
// Get feature variable
const value = flag.getVariable('feature_variable', 'default_value');
console.log('Variable value:', value);
}
// Track an event
await vwoClient.trackEvent('event_name', userContext);
// IMPORTANT: Flush events before function exits
await vwoClient.flushEvents();
}
main();Code Breakdown
- init({ edgeConfig: { shouldWaitForTrackingCalls: true } }): Configures the SDK for edge environments.
- getFlag, trackEvent, and setAttribute: These methods return much faster when using
edgeConfig. - flushEvents(): Required - Call this at the end of your function to send all tracking events.
- Graceful fallback for variables: Always provide a default value to getVariable() to handle missing configurations.
Flushing Events in Edge Environments
When using edgeConfig, you must call flushEvents() at the end of your function to send tracking events to VWO.
Basic Usage
// At the end of your edge function, before returning
await vwoClient.flushEvents();Recommended Approach for Edge: Cached Settings
Key Idea
Fetch settings once, cache them, and reuse them across SDK initializations.
This can be achieved in two ways:
- Explicit settings injection
- Custom storage connector with
getSettings/setSettings
Option 1: Explicit SDK Settings Injection
VWO supports initializing the SDK with pre-fetched settings, completely skipping the network call.
Reference: https://developers.vwo.com/v2/docs/fme-explicit-sdk-fetch-settings
Example
Fetch and Cache Settings (One-Time or Periodic)
const response = await fetch(
`https://dev.visualwebsiteoptimizer.com/server-side-settings?a=${ACCOUNT_ID}&i=${SDK_KEY}`
);
const settings = await response.json();
// Store in KV, Redis, etc.
await KV.put(`vwo_settings_${ACCOUNT_ID}_${SDK_KEY}`, JSON.stringify(settings));Initialize SDK with Cached Settings
const cachedSettings = await KV.get(`vwo_settings_${ACCOUNT_ID}_${SDK_KEY}`);
await init({
accountId: ACCOUNT_ID,
sdkKey: SDK_KEY,
settings: JSON.parse(cachedSettings)
});Benefits
- Zero network calls during request handling.
- Predictable latency.
- Full control over refresh strategy.
When to Use
- You already have a background job or cron job.
- You want explicit control over the settings lifecycle.
- Highly regulated or locked-down environments.
Lifecycle
- VWO Settings API
- Fetch Once (Background / Cron / First Request)
- Store in Edge KV / Redis / Durable Store
- Inject into SDK on init()
Option 2 (Recommended): Custom Storage Connector with getSettings / setSettings
To simplify settings management, the FE SDK now supports settings persistence directly via the storage connector.
Why This Is Better
- No manual settings injection needed
- SDK automatically:
- Reads cached settings via
getSettings - Stores fetched settings via
setSettings
- Reads cached settings via
- Cleaner, more maintainable integration
- Ideal for enterprise edge deployments
Lifecycle
- SDK initializes
- SDK calls
getSettings() - If settings exist → use them
- If not → fetch from VWO servers
- SDK calls
setSettings()to persist them
Platform-Specific Guidance
Cloudflare Workers
Cloudflare worker terminates execution immediately after returning a response. Use ctx.waitUntil() to keep async work alive. To know more about waitUntil, refer to the official docs here
export default {
async fetch(request, env, ctx) {
const vwoClient = await init({
accountId: env.VWO_ACCOUNT_ID,
sdkKey: env.VWO_SDK_KEY,
edgeConfig: {
shouldWaitForTrackingCalls: true,
},
});
const userContext = { id: 'user123' };
// Your application logic
const flag = await vwoClient.getFlag('feature_key', userContext);
await vwoClient.trackEvent('event_name', userContext);
// CRITICAL: Flush events using ctx.waitUntil in Cloudflare
ctx.waitUntil(vwoClient.flushEvents());
return new Response('OK');
}
}Vercel
Similar to Cloudflare, Vercel Edge requires waitUntil(). To know more about waitUntil(), check the official docs here.
import { init } from 'vwo-fme-node-sdk';
import { waitUntil } from '@vercel/functions';
export default async function handler(req, res) {
const vwoClient = await init({
accountId: '123456',
sdkKey: '32-alpha-numeric-sdk-key',
edgeConfig: {
shouldWaitForTrackingCalls: true,
},
});
const userContext = { id: 'user123' };
// Your application logic
const flag = await vwoClient.getFlag('feature_key', userContext);
await vwoClient.trackEvent('event_name', userContext);
// CRITICAL: Flush events using waitUntil in vercel
waitUntil(vwoClient.flushEvents());
return res.status(200).json({status: 'success'})
}
}Other Edge Environments
If the platform does not provide “background work” helpers, simply await the flush call::
export default async function handler(request) {
const vwoClient = await init({
accountId: '123456',
sdkKey: '32-alpha-numeric-sdk-key',
edgeConfig: {
shouldWaitForTrackingCalls: true,
},
});
const userContext = { id: 'user123' };
const flag = await vwoClient.getFlag('feature_key', userContext);
await vwoClient.trackEvent('event_name', userContext);
// REQUIRED: Flush events before returning
await vwoClient.flushEvents();
return new Response('OK');
}Example: Edge KV-Based Storage Connector
Custom Storage Connector
const storageConnector = {
async getSettings(accountId, sdkKey) {
const key = `vwo_settings_${accountId}_${sdkKey}`;
const cached = await KV.get(key);
return cached ? JSON.parse(cached) : null;
},
async setSettings({ settings }) {
const key = `vwo_settings_${settings.accountId}_${settings.sdkKey}`;
await KV.put(key, JSON.stringify(settings), {
expirationTtl: 3600 * 12 // 12 hours
});
}
};SDK Initialization
await init({
accountId: ACCOUNT_ID,
sdkKey: SDK_KEY,
storage: storageConnector
});Best Practices
- ✔ Use edgeConfig: Optimizes performance and defers tracking calls for batch flushing.
- ✔ Always call flushEvents(): Ensures event delivery before function termination.
- ✔ Use Cloudflare/Vercel waitUntil(): Prevents event loss after response is returned.
- ✔ Reuse the SDK instance: Place initialization at the module level to reduce cold-start overhead.
- ✔ Keep user IDs stable: User identity consistency ensures correct bucketing.
- ✔ Monitor execution time: Most edge runtimes enforce 50ms–100ms budgets.
- ✔ Add error handling: Wrap flush calls in try/catch (optional but recommended).
By following this guide, you can confidently deploy the VWO FE JavaScript SDK to distributed, edge platforms while preserving the integrity of your feature flagging and experimentation data.
Updated about 24 hours ago
