Skip to content

Report poller target on poll requests and in the worker heartbeat - #887

Open
veeral-patel wants to merge 7 commits into
mainfrom
vpatel/poller-load-balancing
Open

veeral-patel wants to merge 7 commits into
mainfrom
vpatel/poller-load-balancing

Conversation

@veeral-patel

@veeral-patel veeral-patel commented Oct 20, 2026 •

Copy link
Copy Markdown

What

Adds a worker-reported poller target in two places.

1. On each poll — a new PollerScalingInfo in temporal.api.taskqueue.v1, attached as field 11 to PollWorkflowTaskQueueRequest and PollActivityTaskQueueRequest:

message PollerScalingInfo {
    int32 poller_target = 1;
}

2. On the worker heartbeat — a new field on WorkerPollerInfo:

int32 poller_target = 4;

Why

Sending poller target in each poll will allow us to apply logic to load balance pollers between workers. Sending poller target on the worker heartbeat will let us export a poller target metric on the server side.

Workers report the poller target of the pool issuing each poll so the server
can distribute poller-scaling suggestions fairly across a fleet.

Scaling suggestions ride on dispatched tasks and the matcher is FIFO, so a
worker's share of suggestions tracks its share of pollers. Growth is therefore
proportional to current size, which preserves any imbalance between otherwise
identical workers rather than correcting it. With a reported target the server
can withhold suggestions that would push a worker further from its share.
Comment thread temporal/api/taskqueue/v1/message.proto Outdated
Comment on lines +39 to +44
// Scaling suggestions ride on dispatched tasks, and the matcher hands tasks to waiting
// pollers in FIFO order, so a worker holding a large share of a task queue's pollers
// receives suggestions at a proportionally higher rate. That makes poller growth
// proportional to current poller count, which preserves and amplifies any imbalance
// between otherwise identical workers. Reporting this lets the server withhold
// suggestions that would push a worker further from its share.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I dunno that this needs to go into detail about the specific motivating problem. Can probably just drop the whole paragraph honestly.

Comment thread temporal/api/taskqueue/v1/message.proto Outdated
Co-authored-by: Spencer Judge <spencer@temporal.io>
@veeral-patel
veeral-patel marked this pull request as ready for review October 20, 2026 20:11
@veeral-patel
veeral-patel requested review from a team October 20, 2026 20:11
Workers already report their poller target on each poll so matching can spread
scaling suggestions across a fleet by share. That value is consumed inside the
matching decision and discarded -- nothing persists it, and nothing can observe
it.

Reporting it on the heartbeat as well lets the server read poller target per
worker and export it as a metric, making fleet-wide poller distribution visible
without instrumenting every SDK.

WorkerHeartbeat already carries four separate WorkerPollerInfo sub-messages
(workflow, sticky workflow, activity, nexus), so a single field here gives a
per-task-type breakdown without a new keyed structure, and keeps the
normal-vs-sticky split that TaskQueueType cannot express.
@veeral-patel veeral-patel changed the title Add PollerScalingInfo to poll requests Report poller target on poll requests and in the worker heartbeat Oct 22, 2026
Drop the rich-get-richer explanation from PollerScalingInfo: it is rationale for
the server's matching logic rather than anything a client needs to populate the
field, and it will go stale independently of this proto.

The rest just says less of the same thing, matching the one-to-two line style of
the surrounding fields.
veeral-patel and others added 3 commits October 28, 2026 15:46
CI runs 'make ci-build' and fails if the tree is dirty, and the checked-in
OpenAPI specs are generated output. WorkerHeartbeat is reachable over the HTTP
API via RecordWorkerHeartbeat, so adding a field to WorkerPollerInfo changes
them. The poll-request field needed no regeneration -- the poll RPCs have no
HTTP binding.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants