Skip to content

Disable Default Polling for OFREP Static-Context Providers #68

@jonathannorris

Description

@jonathannorris

Problem

OFREP static-context providers currently poll on a fixed timer by default (JS: 30s, Swift: 30s, Kotlin: 5min). This has two issues:

  1. Sticky bucketing — polling causes flag values to change mid-session, which breaks the expectation that a user sees consistent behavior throughout a session. Most platforms expect bucketing to remain sticky for a user's whole session.

  2. Resource efficiency — timer-based polling is wasteful for static-context providers where the evaluation context rarely changes during a session. This is especially problematic on mobile where it impacts battery life and data usage.

This is out of step with how vendor SDKs handle client-side refresh. DevCycle, LaunchDarkly, Statsig, and Eppo do not use timer-based polling as the default client-side refresh mechanism:

Vendor Default Mechanism Timer Polling?
DevCycle Init + context change + foreground + SSE push No
LaunchDarkly SSE streaming foreground, 60min poll background only No (streams)
Statsig Init + user change only No
Eppo Init only, polling opt-in No (off by default)
ConfigCat Auto polling (60s) Yes
Unleash Polling (30s) Yes

Proposed Solution

Replace default timer-based polling with event-driven refresh for static-context providers. Providers should re-fetch bulk evaluations on:

  1. Initialization (already defined in ADR-0009)
  2. Context change (already handled via onContextChange)
  3. App foreground / page visibility — re-fetch when the app returns from background or the page becomes visible

Timer-based polling should remain available as an opt-in for applications that want it, but default to disabled.

Further details on foreground detection, debouncing, and interaction with SSE (see #62) will follow in an ADR PR.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions