From 4c831bfca72f07c60ffd0450ca53efb74ed58b68 Mon Sep 17 00:00:00 2001 From: rudra717 <52209277+rudra717@users.noreply.github.com> Date: Tue, 7 Apr 2026 23:24:40 -0700 Subject: [PATCH] fix(router): clamp least_busy request counter to prevent negative drift The least_busy router strategy decrements a per-deployment request counter on success/failure callbacks. Under race conditions (callback fires before pre-call, or fires twice), the counter can go negative. A negative count is always less than the 0 assigned to unused deployments, so the negative-count deployment attracts ALL traffic while others starve to zero requests. Fix: clamp the counter with max(value - 1, 0) on all 4 decrement paths (sync success, sync failure, async success, async failure). Fixes BerriAI/litellm#25323 Co-Authored-By: Claude --- litellm/router_strategy/least_busy.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/litellm/router_strategy/least_busy.py b/litellm/router_strategy/least_busy.py index e1614388379..25e0d1e12a1 100644 --- a/litellm/router_strategy/least_busy.py +++ b/litellm/router_strategy/least_busy.py @@ -76,7 +76,7 @@ class LeastBusyLoggingHandler(CustomLogger): request_count_value: Optional[int] = request_count_dict.get(id, 0) if request_count_value is None: return - request_count_dict[id] = request_count_value - 1 + request_count_dict[id] = max(request_count_value - 1, 0) self.router_cache.set_cache( key=request_count_api_key, value=request_count_dict ) @@ -109,7 +109,7 @@ class LeastBusyLoggingHandler(CustomLogger): request_count_value: Optional[int] = request_count_dict.get(id, 0) if request_count_value is None: return - request_count_dict[id] = request_count_value - 1 + request_count_dict[id] = max(request_count_value - 1, 0) self.router_cache.set_cache( key=request_count_api_key, value=request_count_dict ) @@ -144,7 +144,7 @@ class LeastBusyLoggingHandler(CustomLogger): request_count_value: Optional[int] = request_count_dict.get(id, 0) if request_count_value is None: return - request_count_dict[id] = request_count_value - 1 + request_count_dict[id] = max(request_count_value - 1, 0) await self.router_cache.async_set_cache( key=request_count_api_key, value=request_count_dict ) @@ -178,7 +178,7 @@ class LeastBusyLoggingHandler(CustomLogger): request_count_value: Optional[int] = request_count_dict.get(id, 0) if request_count_value is None: return - request_count_dict[id] = request_count_value - 1 + request_count_dict[id] = max(request_count_value - 1, 0) await self.router_cache.async_set_cache( key=request_count_api_key, value=request_count_dict )