Most reviews of residential proxies read like this: "I tried it, pages loaded, it works, 5 stars."
That tells you almost nothing. "It works" is what a proxy does at 10 requests per minute. The question that actually decides whether a pool is usable is what happens at 10,000 — and that question has six specific answers, none of which vendors usually publish.
I've been building scraping pipelines for a few years, and I've started benchmarking every pool the same way before I commit to it. Below is the checklist, plus the numbers I got the last time I ran it.
1. Connection setup cost
This is the metric nobody reports, and for rotating residential pools it's the one that matters most.
With per-request rotation, every single request means a new upstream connection to a new exit node. That handshake is not free. I instrumented it by splitting the request into three phases:
Phase
What it measures
Observed
TCP to gateway
Network distance to the entry point
3–81 ms
SOCKS5 auth + upstream connect
Time to select an exit node and open a tunnel to it
1,083–2,253 ms
TLS + first byte
Actual request through the exit
427–617 ms
The middle row is the one that surprises people. Roughly 1.1 seconds of that was the SOCKS5 username/password exchange alone — two round trips — and the rest was the gateway picking an exit and connecting to it.
Why it matters: if you assume a rotating proxy gives you concurrency / latency requests per second, you're off by an order of magnitude. At 2 seconds of setup per request, 20 concurrent workers get you around 10 req/s, not 200. That's not a defect — it's the physics of "new IP every request". But you have to design around it: raise concurrency, reuse sticky sessions where the target allows it, or both.
Contrast this with a sticky session: you pay the setup once, then subsequent requests through the same exit are just TLS + request. If your target doesn't force rotation, sticky wins on throughput by a wide margin.
2. Success rate — under concurrency, not serially
Anyone can get 100% success with one request at a time. The number that matters is success rate at your production concurrency, because a pool that saturates silently starts returning timeouts, and timeouts look like your code's bug until you measure them separately.
Always bucket results into four outcomes: 2xx, 403/429, timeout, other error. Collapsing them into "success/fail" hides the two failure modes that need completely different fixes — a 403 means the target doesn't like your IP; a timeout means the pool doesn't have capacity.
3. Block rate, with 403 and 429 separated
They mean different things:
- 403 — the target rejected this IP or fingerprint outright. Your problem is IP reputation or headers.
- 429 — you're going too fast for that endpoint. Your problem is pacing. A pool with a 2% 403 rate is a reputation problem. A pool with a 2% 429 rate is probably your own request rate. Reporting them as one "2% failure" number is how people end up buying a new provider when they needed a rate limiter. 4. Traffic efficiency: requests per GB This only applies to GB-billed pools, and it's the number that turns a $/GB price into something you can actually budget. Download one page, measure the bytes, divide. Then: requests_per_GB = 1,073,741,824 / avg_bytes_per_request cost_per_1k = (avg_bytes_per_request * 1000 / 1,073,741,824) * price_per_GB At 80 KB per request and $0.22/GB, 1 GB is roughly 13,000 requests and 1,000 requests cost about $0.017. At 400 KB per request — heavy HTML, lazy-loaded assets — the same GB buys you 2,600 requests. Same price, 5x the cost per page. Pick representative targets. If you benchmark on pages that pull 2 MB of images, your requests-per-GB number will be garbage, and you'll under-budget by a factor of ten. Measure the pages you'll actually scrape. 5. Rotation fidelity Vendors promise things like "rotates every 3–30 minutes" or "new IP per request". Both are testable in about five minutes: sample the exit IP every request and record when it changes. My probe made 8 requests and got 8 distinct exit IPs, from different ISPs (I saw Comcast AS7922 and AS138096 among them). That's genuine per-request rotation of real residential addresses — not a datacenter range wearing a residential ASN, which is the other thing worth checking. If you're promised timed rotation, log the intervals. Median and max matter more than the mean, because a rotation that occasionally sticks for an hour is what gets your session flagged. 6. Geo-targeting accuracy This is where "we cover 195 countries" meets reality. The test: request a specific country (or city), then verify the exit IP's actual geolocation — not the gateway's, the exit's. One thing I learned the hard way: without an explicit targeting parameter, a pool may hand you any country. My first probe on a US-prefixed gateway returned a US address, then an Indonesian one on the next request. That's not a bug — it's a global pool doing what a global pool does. If your task needs US IPs specifically, you must pin the country explicitly and then verify every exit, or you'll quietly collect data from the wrong market. A caveat about my numbers These came from a client in Hong Kong going through a tunnel, so the absolute latency figures are inflated by my own routing. What transfers between environments is the shape: the setup cost dominates, and it's roughly constant regardless of what you're fetching. Run the same split on your own machine before you budget anything — the relative weights are the insight, the absolute milliseconds are local to me. What I'd actually do If you're evaluating a pool, don't ask "does it work". Ask:
- What's the connection setup cost per request, and does sticky session eliminate it?
- What's the success rate at my concurrency?
- Are 403s and 429s separated, and which one is my own fault?
- How many requests do I get per GB on my target pages?
- Does rotation actually match the advertised interval?
- Does geo-targeting survive verification, or am I getting a random country? Six numbers. An afternoon of work. It's the difference between picking a provider and guessing at one. Full disclosure: I'm affiliated with 9HTTP, the residential provider whose gateway I benchmarked here — it's what I had credentials for when I wrote this. The methodology above is provider-agnostic and reproducible with your own pool; the snippet I used splits requests into the three phases described in section 1. If you want to compare, 9HTTP gives 500 MB free on signup, which is enough to run this whole checklist once against your own targets: https://dashboard.9http.com/auth/register?lang=en&utm_source=devto&utm_medium=article&utm_campaign=w1_benchmark&utm_content=metrics_post Pricing for the pool I tested: https://www.9http.com/zh-CN/pricing/residential?utm_source=devto&utm_medium=article&utm_campaign=w1_benchmark&utm_content=metrics_post
Top comments (0)