nodejs / nodejs/undici

Pool distributes load unevenly across connections.

Open
#3,648 9 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

bug Pool
Dominant language
JavaScript
Stars
7.7k
Forks
880
Avg merge
2d 16h
Merged PRs (30d)
68

Description

Bug Description

Pool distributes load unevenly across connections, prioritizing them by creation time. See here.

Where your connections are load-balanced across instances (pods/containers), this results in overuse of some instances and underuse of others.

Reproducible By

  1. Create a service, ServiceA, with an endpoint that takes 100ms - 200ms to respond.
  2. Using Kubernetes, deploy 5 pods with instances of ServiceA.
  3. In another service, ServiceB, create a Pool of connections to ServiceA, referencing it by Kubernetes Service address (https://service-name), such that we'll be load-balancing connections through kube-proxy.
  4. Send 1 request to ServiceB every 50ms for 1 minute.
  5. Observe balanced connections across ServiceA pods, but imbalanced request distribution and resource usage across ServiceA pods.

Thinking through, this may be otherwise observable plainly through internal diagnostics around amount of requests processed by each Client or something like that.

Expected Behavior

Roughly balanced request distribution and resource usage across Clients and ServiceA pods.

Environment

MacOS, Node v18

Additional context

There are a number of ways we could resolve this intelligently. Most simply/crudely though, we could track index of last used client and pick back up next scan from that index to roughly round-robin.

Something like:

...
const totalClients = clients.length;
let clientIndex = (this.lastUsedIndex + 1) % totalClients;

for (let i = 0; i < totalClients; i++) {
  const client = clients[clientIndex];

  if (!client[kNeedDrain]) {
    this.lastUsedIndex = clientIndex;
    return client
  }

  clientIndex = (clientIndex + 1) % totalClients;
}

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the pool connection-selection logic in lib/dispatcher/pool.js around lines 75-87, then review the linked reproduction scenario and any diagnostics for per-client request counts. The change is complete when requests and resource use are roughly balanced across available clients under the described workload, with regression coverage for the observed imbalance.

Written by the indexing model from the issue text.

Assessment

Tech stack
javascript, node.js
Domain
networking
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
42/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.