Skip to content

fix: reserve ephemeral-port headroom for the auto max-connections default#407

Draft
nvzhihanj wants to merge 1 commit into
mainfrom
fix/auto-max-connections-port-headroom
Draft

fix: reserve ephemeral-port headroom for the auto max-connections default#407
nvzhihanj wants to merge 1 commit into
mainfrom
fix/auto-max-connections-port-headroom

Conversation

@nvzhihanj

Copy link
Copy Markdown
Collaborator

Problem

client.max_connections defaults to -1, which resolves to the entire
ephemeral-port range (system_maximum_ports × distinct_endpoints). When
connections are established in a burst — e.g. max_throughput at start-up — the
pool tries to bind every ephemeral port at once. The OS holds recently-closed
ports in TIME_WAIT, so the tail of bind() calls intermittently fails with
EADDRNOTAVAIL ("Cannot assign requested address"). The run recovers, but only
after a burst of dropped/retried connections; it's worst when the client shares a
host with other socket activity.

A connection pool should never try to claim 100% of the ephemeral range — that
leaves nothing for TIME_WAIT recycling, the OS, or other processes on the box.

Fix

Resolve the auto (-1) limit to a fraction of the budget instead of the whole
range, so the zero-config default reserves headroom:

  • AUTO_MAX_CONNECTIONS_BUDGET_FRACTION = 0.5 — auto claims half the per-endpoint
    budget. That is still a large pool (thousands of connections per endpoint) and
    continues to scale with the number of distinct endpoints.
  • An explicit max_connections is unchanged and may still use the full
    budget (the over-budget guard is unchanged).

Also removes the now-dead get_ephemeral_port_limit() / get_used_port_count()
helpers — the static reserve replaces them without reading the racy,
process-global live socket count.

Why this default

The client should work well without the user having to reason about ephemeral
ports or hand-tune max_connections. A static reserve keeps that property: the
default is safe on a busy/co-located host, while workloads that genuinely need
more concurrency add endpoints (the budget scales per distinct destination) or
set an explicit value. Empirically, claiming the full range reliably produced
EADDRNOTAVAIL under a bursty max_throughput start-up, whereas reserving
headroom eliminated it with no change to server-side batch or throughput.

Tests

Updated TestEndpointBudgetScaling for the reserved-headroom default and added a
case asserting the auto limit leaves headroom while an explicit value may use the
full budget.


🤖 Generated with Claude Code

…ault

max_connections=-1 resolved to the entire ephemeral-port range
(system_maximum_ports x distinct_endpoints). Establishing connections in a burst
(e.g. max_throughput at start-up) then tries to bind every ephemeral port at
once; with recently-closed ports held in TIME_WAIT, the tail of bind() calls
intermittently fails with EADDRNOTAVAIL. Resolve the auto limit to a fraction of
the budget (AUTO_MAX_CONNECTIONS_BUDGET_FRACTION = 0.5) so the zero-config
default reserves headroom; an explicit max_connections may still use the full
budget. Remove the now-dead get_ephemeral_port_limit / get_used_port_count.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@github-actions

Copy link
Copy Markdown

MLCommons CLA bot All contributors have signed the MLCommons CLA ✍️ ✅

@github-actions github-actions Bot requested a review from arekay-nv July 12, 2026 01:18

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Code Review

This pull request updates the automatic connection limit calculation to only claim a fraction (50%) of the ephemeral-port budget, leaving headroom for the OS to prevent connection establishment failures. Additionally, unused port-counting utility functions have been removed, and the unit tests have been updated and expanded to verify the new behavior. There are no review comments, and I have no additional feedback to provide.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

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.

1 participant