Skip to content

perf: stop the ollama health probe fetching /api/tags twice per poll - #491

Merged
coaxk merged 1 commit into
mainfrom
perf/ollama-probe-single-tags-fetch
Sep 4, 2026
Merged

perf: stop the ollama health probe fetching /api/tags twice per poll#491
coaxk merged 1 commit into
mainfrom
perf/ollama-probe-single-tags-fetch

Conversation

@coaxk

@coaxk coaxk commented Sep 4, 2026

Copy link
Copy Markdown
Owner

Spotted from the ollama side: subarr-next was hitting /api/tags far more often than the poll interval alone explains. It is not one call per poll, it is two.

The defect

tags = await client.tags()          # call #1, already contains the model list
client.reset_vision_cache()         # clears the cache that exists to prevent this
vision_resolved = await client.resolve_vision_model()
    -> installed_models() -> self.tags()   # call #2, identical payload

reset_vision_cache()'s own docstring says it is for "Settings save + model-pull completion". The health probe is neither, so it invalidated the cache on every poll and the resolver re-fetched what the probe was already holding. Settings polls every 8s, so the cost per poll was 2x /api/tags plus 1x /api/version, indefinitely.

The fix

resolve_vision_model() takes an optional installed list; the probe passes the names it just derived from its own tags() call.

Behaviour is deliberately unchanged in both directions:

  • the cache is still reset each poll, so a model pulled outside subarr is still picked up within one refresh
  • any caller passing nothing fetches exactly as before, which is why the existing test_vision_capability.py suite needed no edits at all

Simply dropping the reset_vision_cache() call would have been a smaller diff but would have stopped noticing externally pulled models, so it was rejected.

Verification

The test pins the cost and the behaviour together, so neither can regress on its own: it asserts exactly one GET /api/tags and that the vision model still resolves.

Confirmed red before the fix, for the right reason:

AssertionError: expected 1 /api/tags per probe, got 2:
['/api/tags', '/api/tags', '/api/version']
  • affected tests: 28 passed (new test plus the whole existing vision suite)
  • full suite: 1985 passed, 6 skipped
  • ruff check and ruff format --check clean

The integrations-health probe read the installed model list for its badges,
then reset the vision cache and called resolve_vision_model, which fetched
the identical /api/tags payload again via installed_models. The Settings
page polls that endpoint every 8 seconds, so every poll cost two identical
GETs, forever, for data already in hand.

resolve_vision_model now accepts an optional installed list and the probe
passes the names it just derived. Behaviour is unchanged in both directions:
the cache is still reset on each poll, so a model pulled outside subarr is
still noticed, and any caller that passes nothing still fetches exactly as
before, which is why the existing vision suite needed no edits.

The test asserts the probe issues exactly one GET /api/tags while still
resolving the vision model, pinning the cost and the behaviour together so
neither can regress alone. Confirmed red first, reporting

  ['/api/tags', '/api/tags', '/api/version']

Full suite: 1985 passed, 6 skipped. ruff check and format clean.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@coaxk
coaxk merged commit 64c3b7b into main Sep 4, 2026
15 checks passed
@coaxk
coaxk deleted the perf/ollama-probe-single-tags-fetch branch September 4, 2026 10:05
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant