feat: add adaptive polling backoff for workers - #491
Open
denisaditya0 wants to merge 2 commits into
Open
Conversation
denisaditya0
force-pushed
the
feature/adaptive-polling
branch
2 times, most recently
from
July 15, 2026 18:53
ddd4849 to
5d9ed69
Compare
cschleiden
reviewed
Aug 20, 2026
| @@ -0,0 +1,118 @@ | |||
| ## Problem | |||
Author
There was a problem hiding this comment.
done, sorry for late response
cschleiden
force-pushed
the
feature/adaptive-polling
branch
from
August 20, 2026 04:02
5d9ed69 to
7d289a9
Compare
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.
Problem
When workers are idle, pollers hit the database at a fixed interval (default 200ms). With many pollers this creates significant unnecessary DB load. For example, 20 pollers at 200ms = 100 queries/sec per queue, even when there are no tasks.
In production scenarios with multiple queues and higher poller counts (e.g., 150 pollers total), this translates to ~750 queries/sec of pure overhead during idle periods.
Current workaround
The only option today is to manually increase
PollingInterval(e.g., from 200ms to 1-2s) and reduce poller count. This reduces idle load but introduces a permanent trade-off: task pickup latency is always slower, even under load when fast response matters.There's no way to get fast pickup under load AND low DB pressure when idle with a fixed interval.
Solution
Add optional exponential backoff on consecutive empty polls. The interval resets immediately when a task is found, ensuring fast pickup under load.
This gives the best of both worlds:
New options
MaxPollingInterval0(disabled)BackoffMultiplier2.0These are exposed for both workflow and activity workers:
MaxWorkflowPollingInterval/WorkflowPollingBackoffMultiplierMaxActivityPollingInterval/ActivityPollingBackoffMultiplierUsage
Behavior
Each poller maintains its own independent interval. No shared state, no mutex, no coordination overhead.
Benchmark results
Task pickup latency when busy is unchanged (immediate
continueon task found, same as before).Backward-compatible
MaxPollingInterval = 0(default) preserves exact current behaviorImplementation details
time.Tickerwithtime.Timer+ manualReset()to support variable intervalsbackoff()is a simple pure function:next = min(current * multiplier, max)continuefast-path on task found is preserved, no regression in throughputChanges
internal/worker/worker.gobackoff()helper, new fields inWorkerOptionsworker/options.goworker/worker.gointernal/worker/worker_test.goTest coverage