Skip to content

Disable Default Polling for OFREP Static-Context Providers #68

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
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions