fix(rerank): back off between retries instead of spinning - #441
Merged
Conversation
All three rerank providers retried 429 and 5xx responses with a bare `continue`, so the entire retry budget was spent within milliseconds of the first rejection. That is useless against a per-minute quota, which is exactly what hosted rerank endpoints enforce: the caller burns three attempts and still fails, while the window it needed to wait out had barely started. Observed while driving the LoCoMo agentic suite against a hosted rerank endpoint — search requests failed outright with RerankServiceError while the endpoint itself was healthy and merely pacing us. Adds `_errors.backoff_sleep()` (exponential with full jitter, capped at 8s) and wires it into the vLLM, DeepInfra and DashScope retry loops. The jitter keeps a batch of concurrent searches from re-colliding after they trip the limit together. No behaviour change when the endpoint is healthy: the sleep only runs on a retryable failure that will be retried. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Kendrick-Song
approved these changes
Sep 8, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
All three rerank providers retried 429 / 5xx with a bare
continue, so the wholeretry budget was spent within milliseconds of the first rejection. Against a
per-minute quota — which is what hosted rerank endpoints enforce — that is a
guaranteed failure: three attempts burn instantly and the caller gives up while
the window it needed to wait out has barely started.
Surfaced while driving the LoCoMo agentic suite against a hosted rerank endpoint.
Search requests failed with
RerankServiceErroreven though the endpoint washealthy and merely pacing us.
Adds
_errors.backoff_sleep()— exponential, full jitter, capped at 8s — andwires it into the vLLM, DeepInfra and DashScope retry loops. Jitter matters here
because a batch of concurrent searches trips the limit together and would
otherwise re-collide on every retry.
No behaviour change on a healthy endpoint: the sleep runs only on a retryable
failure that is actually going to be retried. A 4xx that is not 429 still raises
immediately.
Area
Verification
New regression test
test_429_retry_waits_between_attemptspatchesasyncio.sleepand asserts one wait per failed attempt — it fails if thebackoff is removed.
Field evidence: with the old code an agentic LoCoMo pass logged 84 provider-side
failures on the query path; with backoff plus a larger retry budget the same pass
completed with zero.
Checklist
main..envfiles, dependency folders, or generated output.No doc update: this is internal retry behaviour with no configuration surface.
max_retriesalready existed and is unchanged.Notes for Reviewers
Worth a look at the constants (
_BACKOFF_BASE_SECONDS = 0.5, cap 8s). With thedefault
max_retries = 3the worst case adds ~3.5s before giving up, averaging~1.75s with jitter. If that is too patient for a latency-sensitive deployment,
the base is the knob to turn.
DashScope raises
RerankErrorrather than going throughupstream_http_error,so its retry arm is shaped slightly differently from the other two — the backoff
call sits in the same place regardless.
🤖 Generated with Claude Code