Where: oxyroute/resilience.py:9-78.
self.min_rtt is a running minimum that is set once and never decays/resets, and it's shared across all endpoints/routes rather than tracked per-route or in a sliding window.
on_request_completed is invoked from access_log_hook for every response including fast 404s and even the limiter's own 503 rejections, dragging min_rtt toward near-zero.
- As
min_rtt / avg_rtt trends toward 0, the Vegas-style gradient computation drives current_limit down toward min_limit permanently, increasing rejections, which are themselves fast and further lower min_rtt — a feedback loop that ratchets concurrency down and never recovers.
- Separately,
as_access_log_hook's wrapped hook receives duration_seconds per its parameter name, but App.__rsgi__ (oxyroute/app.py:812) passes duration in milliseconds — units mismatch compounds the above.
Fix direction: use a windowed/decaying minimum (not all-time), exclude non-2xx and self-rejected requests from the RTT sample, track per-route or use a global gradient with a sqrt(limit)-style headroom term (as in TCP Vegas/gradient2), and fix the seconds-vs-milliseconds mismatch.
Where:
oxyroute/resilience.py:9-78.self.min_rttis a running minimum that is set once and never decays/resets, and it's shared across all endpoints/routes rather than tracked per-route or in a sliding window.on_request_completedis invoked fromaccess_log_hookfor every response including fast 404s and even the limiter's own 503 rejections, draggingmin_rtttoward near-zero.min_rtt / avg_rtttrends toward 0, the Vegas-style gradient computation drivescurrent_limitdown towardmin_limitpermanently, increasing rejections, which are themselves fast and further lowermin_rtt— a feedback loop that ratchets concurrency down and never recovers.as_access_log_hook's wrapped hook receivesduration_secondsper its parameter name, butApp.__rsgi__(oxyroute/app.py:812) passes duration in milliseconds — units mismatch compounds the above.Fix direction: use a windowed/decaying minimum (not all-time), exclude non-2xx and self-rejected requests from the RTT sample, track per-route or use a global gradient with a
sqrt(limit)-style headroom term (as in TCP Vegas/gradient2), and fix the seconds-vs-milliseconds mismatch.