Skip to content

Redundant API requests for providers on settings page when multiple features share the same capability #541

Description

@hbhalodia

What problem does this address?

Summary

The AI Settings page makes duplicate GET requests to /ai/v1/providers?capability=<capability> for every feature that has developer mode enabled. Since most features share the same capability (e.g., text_generation), this results in many identical network requests firing simultaneously when the page loads.

Steps to Reproduce

  1. Enable multiple AI features that share the same capability (e.g., several features using text_generation).
  2. Enable Developer Mode (Model selection) from the settings page dropdown menu.
  3. Open the browser Network tab.
  4. Load/reload the AI Settings page.

Expected Behavior

One request per unique capability value (e.g., one for text_generation, one for vision, one for image_generation — totaling ~3 requests).

Actual Behavior

A separate request is made for every feature's DeveloperSettings component instance, even when they have the same capability. For example, if 8 features use text_generation, 8 identical requests to providers?capability=text_generation are fired in parallel.

In the attached video/screenshot, you can see ~10+ requests to the same providers?capability=text_generation&_locale=user endpoint, each taking 0.5–1s, resulting in unnecessary network load, slower page rendering, and increased server resources.

Screen.Recording.2026-05-13.at.3.44.58.PM.mov

Root Cause

Each DeveloperSettings component independently fetches providers in its own useEffect based on the capability prop. There is no shared state or request deduplication — so if 10 components mount with the same capability, 10 identical API calls are made.

Impact

  • Unnecessary network bandwidth and server load.
  • Slower settings page load — the waterfall of redundant requests delays DOMContentLoaded and full page finish time.

What is your proposed solution?

Possible Solution

Introduce a shared caching layer for provider fetches, keyed by capability. Instead of each DeveloperSettings instance making its own API call, a centralized function (or custom hook like useProviders) would:

  1. Deduplicate in-flight requests — When the first component requests text_generation, it initiates the fetch. Any subsequent component requesting the same capability during that fetch attaches to the existing promise rather than creating a new one.
  2. Cache resolved results — Once a capability's providers are fetched, the result is stored in a module-level cache (e.g., a Map<string, Promise<ProviderData[]>>). Later mounts with the same capability resolve immediately from cache without a network call.
  3. Allow retries on failure — If a fetch fails, evict it from the cache so that future component mounts can attempt the request again.

This ensures the number of requests equals the number of unique capabilities (typically 2–3), not the number of feature instances using developer mode (currently 10+).

Use of AI Tools

  • Use GitHub Copilot with Claude 4.6 Opus to create the issue description, Reviwed manually and then used it to issue description.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    Status
    Done

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions