From 83d0c186a74bd2e44e17e297f4bc81a1ce028e1c Mon Sep 17 00:00:00 2001 From: Nick Craig-Wood Date: Fri, 6 Feb 2026 13:02:18 +0000 Subject: [PATCH] pacer: re-read the sleep time as it may be stale MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Before this change we read sleepTime before acquiring the pacer token and uses that possibly stale value to schedule the token return. When many goroutines enter while sleepTime is high (e.g., 10s), each goroutine caches this 10s value. Even if successful calls rapidly decay the pacer state to 0, the queued goroutines still schedule 10s token returns, so the queue drains at 1 req/10s for the entire herd. This can create multi‑minute delays even after the pacer has dropped to 0. After this change we refresh the sleep time after getting the token. This problem was introduced by the desire to skip reading the pacer token entirely when sleepTime is 0 in high performance backends (eg s3, azure blob). --- lib/pacer/pacer.go | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/lib/pacer/pacer.go b/lib/pacer/pacer.go index 494340638..d23d1ce33 100644 --- a/lib/pacer/pacer.go +++ b/lib/pacer/pacer.go @@ -168,6 +168,12 @@ func (p *Pacer) beginCall(limitConnections bool) { if sleepTime > 0 { <-p.pacer + // Re-read the sleep time as it may be stale + // after waiting for the pacer token + p.mu.Lock() + sleepTime = p.state.SleepTime + p.mu.Unlock() + // Restart the timer go func(t time.Duration) { time.Sleep(t)