Draft: Add feature flags caching starter doc

What does this MR do and why?

Adds doc/operations/feature_flags_caching.md, documenting how customers can implement an HTTP cache in front of the feature flags API, and warns on the existing page about a failure mode that currently has no documentation.

Why now.

The page's only scaling guidance is the Unleash Proxy, which reaches planned end of life on 2026-11-26. Its upstream successor, Unleash Edge, does not work against the GitLab API. After November, a reader who needs to scale past the rate limit has nothing to follow.

The Proxy is not doing anything unusual. It polls the API on a schedule and serves many clients from one cached copy, which any HTTP cache can do. What has been missing is a statement of the constraints this API imposes, several of which are not obvious from its responses.

The most important one is a silent failure. If UNLEASH-APPNAME is missing or empty, the API returns 200 OK with an empty flag list rather than an error. Unleash SDKs read an empty list as every flag being disabled, so a fleet can lose every flag at once with nothing logged. Any proxy that strips unknown headers produces this. The MR adds a warning to Get access credentials as well as to the new page, because it affects readers who never build a cache.

Other constraints the new page documents:

  • Neither UNLEASH-APPNAME nor UNLEASH-INSTANCEID appears in Vary, so both must be added to the cache key by hand or environments cross-serve.
  • The API sends Cache-Control: max-age=0, private, must-revalidate, so a compliant shared cache stores nothing until configured to ignore it.
  • An ETag is returned and If-None-Match yields 304, but a 304 still counts against the rate limit — throttling happens before the request reaches the application. Conditional requests save bandwidth, not quota.
  • Returning an empty flag list when GitLab is unreachable disables every feature during an incident. Serving stored data is safer.

Verification.

The example NGINX configuration was built and tested against the live API on 2026-09-22, passing nine behavioural checks: cache hit, environment isolation, blank app name refused without reaching GitLab, invalid and blank credentials handled, 50 concurrent cold clients producing exactly one upstream request with all 50 served, register and metrics absorbed, stored data served with the origin unreachable, and the same after a restart.

Every request in that lab came from curl. No Unleash SDK has been pointed at the configuration, so the optional handling of register and metrics is verified at the HTTP level only. It is documented as optional for that reason.

#627488

Edited by Darren Eastman

Merge request reports

Loading
Loading