Handle Offline and Edge Scenarios
Why handle offline and edge scenarios
Section titled “Why handle offline and edge scenarios”Not every application has reliable, low-latency access to the Optimizely CDN. Mobile apps go underground, IoT devices operate in disconnected facilities, and edge workers need sub-millisecond decisions without origin round-trips. Offline-first patterns ensure flag decisions are always available, even when the network is not.
What you will do
Section titled “What you will do”- Implement a cached datafile fallback for offline mode
- Deploy flag evaluation at the edge using workers
- Configure the Optimizely Edge Agent
- Handle eventual consistency between cached and live data
Step 1: Offline fallback with bundled datafile
Section titled “Step 1: Offline fallback with bundled datafile”Bundle a datafile snapshot with your application so it can serve decisions without any network access.
import { createInstance } from '@optimizely/optimizely-sdk';
import bundledDatafile from './datafile-snapshot.json';
// Initialize with the bundled datafile -- works offline
const optimizely = createInstance({
datafile: bundledDatafile,
sdkKey: 'YOUR_SDK_KEY', // Attempt live updates when online
datafileOptions: {
autoUpdate: true,
updateInterval: 60_000,
},
});
// SDK serves decisions immediately from the bundle
// When online, it polls for updates in the background
const user = optimizely.createUserContext('user-789');
const decision = user.decide('offline_capable_flag'); import json
from optimizely import optimizely as opti
# Load bundled snapshot
with open('datafile-snapshot.json') as f:
bundled = json.load(f)
client = opti.Optimizely(datafile=json.dumps(bundled))
# Serve decisions offline
user = client.create_user_context('user-789')
decision = user.decide('offline_capable_flag') using OptimizelySDK;
// Load bundled snapshot from embedded resource
var bundled = File.ReadAllText("datafile-snapshot.json");
var optimizely = OptimizelyFactory.NewDefaultInstance(
"YOUR_SDK_KEY",
fallbackDatafile: bundled
);
var user = optimizely.CreateUserContext("user-789");
var decision = user.Decide("offline_capable_flag"); Automate datafile snapshots in your CI/CD pipeline. Fetch the latest datafile during build and include it as a static asset.
# Add to your CI build script
curl -s "https://cdn.optimizely.com/datafiles/YOUR_SDK_KEY.json" \
-o src/datafile-snapshot.json
echo "Datafile snapshot updated at build time" Step 2: Edge worker deployment
Section titled “Step 2: Edge worker deployment”Run flag evaluations inside edge workers (Cloudflare Workers, AWS Lambda@Edge, Vercel Edge Functions) for sub-millisecond decisions close to your users.
import { createInstance } from '@optimizely/optimizely-sdk/dist/optimizely.lite.min.js';
export default {
async fetch(request, env) {
// Load datafile from KV store (pre-populated by a cron trigger)
const datafile = await env.OPTIMIZELY_KV.get('datafile', 'json');
if (!datafile) {
return new Response('Datafile unavailable', { status: 503 });
}
const optimizely = createInstance({ datafile });
const userId = request.headers.get('x-user-id') || 'anonymous';
const user = optimizely.createUserContext(userId, {
country: request.cf?.country || 'US',
});
const decision = user.decide('edge_experiment');
return new Response(JSON.stringify({
enabled: decision.enabled,
variation: decision.variationKey,
variables: decision.variables,
}), {
headers: { 'Content-Type': 'application/json' },
});
},
}; Keep edge datafiles fresh
Section titled “Keep edge datafiles fresh”Use a scheduled trigger or webhook to update the datafile in your edge key-value store whenever it changes.
export default {
async scheduled(event, env) {
const response = await fetch(
`https://cdn.optimizely.com/datafiles/${env.SDK_KEY}.json`
);
const datafile = await response.json();
await env.OPTIMIZELY_KV.put('datafile', JSON.stringify(datafile));
},
}; Step 3: Optimizely Edge Agent
Section titled “Step 3: Optimizely Edge Agent”To deploy the Edge Agent:
- Clone the Optimizely Edge Agent repository from GitHub
- Configure your SDK key and target environment in the settings
- Deploy to your edge platform (Cloudflare Workers, AWS Lambda@Edge)
- Route experiment traffic through the edge agent URL
- The agent evaluates flags at the edge and returns decisions in the response headers
The Edge Agent handles datafile caching, polling, and event dispatch. Your application reads decision headers instead of calling the SDK directly.
Step 4: Handle eventual consistency
Section titled “Step 4: Handle eventual consistency”Offline and edge environments operate on cached data. When the live configuration changes, there is a delay before cached copies update. Design for this.
| Pattern | Approach |
|---|---|
| Accept staleness | Most flag changes are additive. A slightly stale datafile returns the previous variation — safe for most experiments |
| Version checking | Compare datafile.revision against the latest known revision. Alert if drift exceeds a threshold |
| Graceful unknown flags | New flags return enabled: false from stale datafiles. Your code already handles this if you follow default-off patterns |
| Cache TTL | Reject cached datafiles older than a configurable maximum age. Fall back to a hardcoded default state |
Verification checklist
Section titled “Verification checklist”- Application starts and serves decisions without network access
- Edge worker returns decisions in under 10ms
- Datafile updates propagate to the edge within the polling interval
- Unknown flag keys return
enabled: falsewithout errors - Events are queued when offline and dispatched when connectivity resumes
Troubleshooting
Section titled “Troubleshooting”| Issue | Cause | Fix |
|---|---|---|
| Worker returns 503 | Datafile not in KV store | Verify the cron trigger or webhook is populating the store |
| Decisions differ edge vs origin | Different datafile revisions | Ensure both use the same SDK key and environment |
| Events lost at the edge | No event forwarding configured | Route events to logx.optimizely.com from the worker |
| Performance Edge flicker | Snippet not configured for edge | Enable Performance Edge in project settings |