Skip to content

Handle Offline and Edge Scenarios

⏱ 25 minutes advanced

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.

  1. Implement a cached datafile fallback for offline mode
  2. Deploy flag evaluation at the edge using workers
  3. Configure the Optimizely Edge Agent
  4. 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.

Bundle a datafile for offline use
javascript
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');
python
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')
csharp
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.

CI pipeline: fetch datafile at build time
bash
# 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"

Run flag evaluations inside edge workers (Cloudflare Workers, AWS Lambda@Edge, Vercel Edge Functions) for sub-millisecond decisions close to your users.

Cloudflare Worker with Optimizely
javascript
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' },
    });
  },
};

Use a scheduled trigger or webhook to update the datafile in your edge key-value store whenever it changes.

Cron trigger to refresh edge datafile
javascript
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));
  },
};

To deploy the Edge Agent:

  1. Clone the Optimizely Edge Agent repository from GitHub
  2. Configure your SDK key and target environment in the settings
  3. Deploy to your edge platform (Cloudflare Workers, AWS Lambda@Edge)
  4. Route experiment traffic through the edge agent URL
  5. 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.

Offline and edge environments operate on cached data. When the live configuration changes, there is a delay before cached copies update. Design for this.

PatternApproach
Accept stalenessMost flag changes are additive. A slightly stale datafile returns the previous variation — safe for most experiments
Version checkingCompare datafile.revision against the latest known revision. Alert if drift exceeds a threshold
Graceful unknown flagsNew flags return enabled: false from stale datafiles. Your code already handles this if you follow default-off patterns
Cache TTLReject cached datafiles older than a configurable maximum age. Fall back to a hardcoded default state
  • 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: false without errors
  • Events are queued when offline and dispatched when connectivity resumes
IssueCauseFix
Worker returns 503Datafile not in KV storeVerify the cron trigger or webhook is populating the store
Decisions differ edge vs originDifferent datafile revisionsEnsure both use the same SDK key and environment
Events lost at the edgeNo event forwarding configuredRoute events to logx.optimizely.com from the worker
Performance Edge flickerSnippet not configured for edgeEnable Performance Edge in project settings