Most proxy pools die quietly. Nothing throws an exception, and one morning a third of your requests time out while the dashboard still says 200 OK — because a scraper that retries three times and finally succeeds looks identical to one that never had a problem.
That is the real failure mode: you are measuring your application, not your infrastructure.
Why "it works" is not a health check
A ping is not a proxy check, and neither is a TCP connect. What you need is whether a complete, correctly authenticated protocol exchange can carry traffic now — and how fast:
| Layer | What breaks | A naive check reports |
|---|---|---|
| Network | Host unreachable, port filtered | Down (correct) |
| TCP | Port open, no service behind it | Up (wrong) |
| Protocol | Handshake rejected, bad credentials | Up (wrong) |
| Identity | Exit IP moved, or is not where you expect | Up (wrong) |
| Capacity | Handshake fine, throughput collapsed | Up (wrong) |
Only the first row is caught by a ping — which is why a pool reporting "100% alive" can still cost you a day.
The five metrics that matter
Track these per endpoint, not per pool — averages hide the endpoints you need to evict.
| Metric | Definition | Why it earns its place |
|---|---|---|
| Handshake latency | Time to complete protocol negotiation | Earliest sign of congestion |
| Rolling success rate | Successes / attempts over last N runs | Catches flapping, not just hard down |
| Exit IP stability | Did the observed exit IP change | Detects rotation you did not ask for |
| Exit IP correctness | Is the exit in the expected region and ASN | Catches silent rerouting |
| Throughput | Bytes per second on a fixed transfer | Catches "connected but useless" |
Latency alone is not enough: a common trick is an endpoint that handshakes in 40 ms and then delivers 30 KB/s — the metric looks great while your pipeline stalls.
Measuring it with stdlib Python
You do not need a framework — a socket, a timer, and a small request are the whole check. The SOCKS5 version, following RFC 1928:
import socket, struct, time
def socks5_check(host, port, user=None, pwd=None, timeout=8.0):
"""Return (ok, handshake_ms, error)."""
t0 = time.perf_counter()
try:
s = socket.create_connection((host, port), timeout=timeout)
except OSError as e:
return False, None, 'tcp:%s' % e
try:
s.sendall(b'\x05\x02\x00\x02' if user else b'\x05\x01\x00')
ver, method = s.recv(2)
if ver != 5 or method == 0xFF:
return False, None, 'no acceptable auth method'
if method == 0x02: # RFC 1929 user/pass exchange
u, p = user.encode(), pwd.encode()
s.sendall(b'\x01' + bytes([len(u)]) + u + bytes([len(p)]) + p)
if s.recv(2)[1] != 0x00:
return False, None, 'auth rejected'
# CONNECT 1.1.1.1:443 -> reply VER REP RSV ATYP BND.ADDR BND.PORT
s.sendall(b'\x05\x01\x00\x01' + socket.inet_aton('1.1.1.1') + struct.pack('!H', 443))
rep = s.recv(10)[1]
if rep != 0x00:
return False, None, 'REP=0x%02x' % rep
return True, (time.perf_counter() - t0) * 1000, None
except (OSError, IndexError) as e:
return False, None, 'handshake:%s' % e
finally:
s.close()
The timing wraps the entire exchange, not just connect() — that is what makes it a metric about the proxy rather than the network. And the structured error string matters: when half the pool fails at once, tcp: versus REP=0x05 separates a routing incident from a credentials incident.
To verify the exit IP, reuse the socket after the handshake: send GET / HTTP/1.1 with Host: api.ipify.org and read the body. A stable exit IP is a feature you pay for; a changing one is either a documented rotating product or a misconfiguration.
Thresholds worth alerting on
Absolute latency means little without your route, so set thresholds against a rolling per-endpoint baseline:
| Signal | Condition | Action |
|---|---|---|
| Latency drift | p95 > 2× 7-day baseline | Warn — usually congestion |
| Success rate | < 95% over last 20 runs | Quarantine the endpoint |
| Consecutive failures | 3 in a row | Evict from the active set |
| Exit IP change | Any change outside a maintenance window | Warn, verify it is intended |
| Throughput | < 50% of baseline for 3 runs | Demote; keep alive but deprioritize |
The key word is quarantine, not delete. Keep a failing endpoint in a slow retry lane so it can re-earn its place — endpoints that fail during a maintenance window come back; endpoints that fail for three days do not.
Common mistakes
1. Checking the pool average instead of per endpoint. A pool at 90% success looks healthy until you notice all 10% of failures are the same three endpoints serving your most important account.
2. Only testing on failure. A check that runs when the pipeline breaks is a debugger, not a monitor. Run it on a schedule independent of traffic.
3. Treating one failure as death. Transient packet loss is real, so require a few consecutive failures before evicting.
4. Ignoring time of day. Your provider's peak hours are not yours, so compare like with like.
5. Forgetting the identity layer. Latency and success rate say nothing about whether the exit is still in the country you need. Check exit IP, region, and ASN together.
6. One aggressive probe. A tight loop looks like an attack and gets your IP rate-limited. Space your probes and rotate your sample.
FAQ
How often should I probe each endpoint?
A rolling sample every 2-5 minutes is plenty for a pool in the dozens. Probing everything every 30 seconds buys nothing and looks abusive.
What success rate should I target?
For a static pool, 95% over a 20-run window is a reasonable floor. For rotating pools expect lower and push the burden onto bounded per-request retries.
Does a failed UDP check mean the proxy is broken?
Usually not. Most SOCKS5 and HTTP proxy products do not forward UDP at all, so for HTTP or TCP workloads a UDP failure is expected.
How do I know a high-latency endpoint is actually bad?
Measure throughput, not just handshake time. Some endpoints negotiate fast and then collapse on bulk transfer; a fixed-size transfer test on a small slice of the pool surfaces them.
Where to go next
The signals above match what our public checking tools expose — a reference to compare your script against:
- Proxy line availability tester (SOCKS5/HTTP handshake, latency grading, exit IP geolocation) — https://socks5ip.com.cn/zuixinzixun/zonghejiaocheng/dailiipcesugongjushiyongzhinan/
- IP quality check center (residential vs datacenter, purity signals) — https://socks5ip.com.cn/ip-check-center/
- Full platform comparison, one page per provider — https://socks5ip.com.cn/dailiip-jiage-duibi/
Measure first, then buy. A pool whose health you can see beats a slightly cheaper pool you have to guess about.
Top comments (0)