On large scrapes and proxy-checker runs, a client can start throwing intermittent connection failed or address already in use errors even though CPU, RAM, and bandwidth are nowhere near saturated. That is almost never a ColdProxy limit; it is the operating system running out of local ephemeral (source) TCP ports because closed sockets accumulate in TIME_WAIT faster than they drain. This page shows how to widen the ephemeral port range and shorten TIME_WAIT on Windows and Linux, plus the ColdProxy-side levers that cut the connection churn at its source.
Symptom
Under heavy concurrency, requests fail intermittently while the machine looks idle:
- Errors like
connection failed,address already in use,WSAEADDRINUSE(Windows), orEADDRNOTAVAIL(Linux), appearing in bursts rather than constantly. - Spare CPU, RAM, and network headroom: the box is not overloaded.
- Failures scale with concurrency: a few hundred workers are fine, a few thousand start failing.
- The same proxy string works perfectly in a single-threaded test, so the credentials and ports are not the problem.
If a single request fails consistently, this is not port exhaustion; check credentials, auth mode, and port range first in Common errors & fixes, then confirm the proxy with Verify your proxy.
Cause
Every outbound TCP connection consumes one ephemeral source port on the client. When the connection closes, that port sits in the TIME_WAIT state before it can be reused, a deliberate TCP safeguard against stray late packets from the old connection landing on a new one.
Two OS defaults make this a bottleneck at scale:
- A small ephemeral port range. Windows defaults to roughly 16,000 dynamic ports (
49152–65535). At a few thousand new connections per second, that pool empties fast. - A long
TIME_WAIT. Windows holds closed connections inTIME_WAITfor about 120 seconds. Ports tied up for two minutes drain far slower than a busy scraper allocates them.
Range divided by TIME_WAIT sets a hard ceiling on new connections per second. With ~16,000 ports and a 120-second hold, sustained churn exhausts the pool and new connections fail until ports recycle, regardless of how many proxy ports your plan provisions.
Linux is usually less prone to this out of the box (a wider default range and shorter FIN/TIME_WAIT handling), but the same exhaustion happens on Linux scrapers running enough concurrency.
Windows fix
Run an elevated (Administrator) terminal; these settings change OS networking and require admin rights. They persist across reboots.
Widen the ephemeral port range
Expand the dynamic (ephemeral) TCP port pool. A conservative range that avoids the well-known and registered low ports:
netsh int ipv4 set dynamicport tcp start=10000 num=55000You can go wider with start=1025 num=64511, but a very low start can clash with local services that bind fixed ports in that range. Start conservative and only widen if you still hit the ceiling.
Shorten TIME_WAIT
Reduce how long closed connections linger in TIME_WAIT. The registry value is the reliable form across Windows builds:
reg add "HKLM\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters" /v TcpTimedWaitDelay /t REG_DWORD /d 30 /f30 (seconds) is a safe floor. Very low values slightly raise the small risk that a stray late packet from an old connection is misrouted onto a new one; 30 keeps that risk negligible while freeing ports far faster than the 120-second default. There is no netsh command that sets TcpTimedWaitDelay on modern Windows; the registry value above is the only supported method.
Verify
Confirm the new range took effect:
netsh int ipv4 show dynamicport tcpThe output should report the start port and number of ports you set. The TcpTimedWaitDelay change applies to new connections after the setting is written (a reboot guarantees it everywhere).
Linux equivalent
On Linux, set the same two levers (and enable safe TIME_WAIT socket reuse) in /etc/sysctl.conf, then reload. This requires root.
# /etc/sysctl.conf
net.ipv4.ip_local_port_range = 10000 65535
net.ipv4.tcp_fin_timeout = 30
net.ipv4.tcp_tw_reuse = 1sysctl -pip_local_port_range widens the ephemeral pool, tcp_fin_timeout shortens how long sockets sit in FIN-WAIT, and tcp_tw_reuse lets the kernel safely reuse a TIME_WAIT socket for a new outbound connection when it is safe to do so.
Before / after comparison
The tuned values raise the per-second connection ceiling by both enlarging the port pool and recycling each port sooner:
| Setting | Default (Windows) | After tuning |
|---|---|---|
| Ephemeral port range | 49152–65535 (~16k ports) |
10000–64999 (~55k ports) |
TIME_WAIT hold |
~120 seconds | 30 seconds |
| Approx. sustainable new connections/sec | ~130 | ~1,800+ |
| Result under heavy concurrency | Intermittent address in use |
Ports recycle fast enough to keep up |
These commands change OS networking globally, for every process on the machine, not just your scraper. Apply them deliberately on dedicated machines that drive many proxy connections, not on a shared workstation or server where other services depend on the default port behavior.
ColdProxy-side levers
OS tuning raises the ceiling, but the most effective fix is to open fewer connections in the first place. Reducing connection churn helps far more than widening the port range alone:
- Reuse connections. Use HTTP keep-alive and a pooled client (a
requests.Session, anhttpxclient, a Node agent withkeepAlive: true) instead of opening a fresh socket per request. One reused socket consumes one ephemeral port across many requests. - Use sticky sessions where the workflow allows. Holding one exit IP for a multi-step flow lets the underlying connection stay open instead of re-dialing per request. See Sticky vs rotating sessions for when to pin an IP versus rotate.
- Cap concurrency to what the workload needs. A bounded worker pool with sensible request pacing collects public data just as fast while generating a fraction of the socket churn, and is gentler on the target site.
import requests
# One pooled session reuses sockets instead of one socket per request
session = requests.Session()
proxy = "http://USERNAME:PASSWORD@gw-2312.coldproxy.com:30000"
session.proxies = {"http": proxy, "https": proxy}
for _ in range(1000):
session.get("https://api.vipv6proxy.com/api/checker/my-ip", timeout=30)Pair connection reuse with a held sticky session for multi-step jobs, and rotate only when the workload genuinely needs a fresh IP. The combination keeps ephemeral-port usage low without any OS tuning. Confirm a tuned client behaves with the Proxy Checker and read your exit IP with My IP.