Why your own test beats any review
Proxy performance depends on the target, the location, the time of day and how you send requests. Reviews and benchmarks published elsewhere test someone else's targets with someone else's code. They can help you build a shortlist, but they can't tell you which provider will work best for you. A two-hour test on your own targets can.
This is the method we recommend. It works for residential, ISP, datacenter and mobile proxies.
What to measure
| Metric | Why it matters |
|---|---|
| Success rate | Share of requests that return correct content (not just HTTP 200) |
| Latency (median and p95) | Speed and long-tail timeouts |
| Bytes per successful request | Determines per-GB cost |
| Session stability | How long sticky sessions actually hold |
| IP diversity | Unique IPs, subnets and ASNs in your sample |
| Geo accuracy | Whether IPs are where you asked |
| Error types | Timeouts vs 403s vs CAPTCHAs vs connection errors |
| Cost per 1,000 successes | The number that decides |
Step 1: Choose targets and define success
Pick 3 to 5 real target URLs, including the hardest one you'll need. Define success precisely: for a product page, maybe "status 200 and the price element is present". A 200 OK block page isn't a success.
Step 2: Fix the test conditions
- Same code for every provider.
- Same headers and client.
- Same concurrency.
- Same time window (run providers in parallel if possible).
- Same targeting settings (country, session type).
Step 3: Run the test
A simple Python harness:
import time, statistics, collections, requests
from concurrent.futures import ThreadPoolExecutor
def one(proxy_url, url, marker):
t = time.time()
try:
r = requests.get(url, proxies={"http": proxy_url, "https": proxy_url}, timeout=30,
headers={"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0 Safari/537.36",
"Accept-Language": "en-US,en;q=0.9"})
ok = r.status_code == 200 and marker in r.text
return ok, time.time() - t, len(r.content), str(r.status_code)
except requests.RequestException as e:
return False, time.time() - t, 0, type(e).__name__
def bench(proxy_url, url, marker, n=500, workers=10):
with ThreadPoolExecutor(workers) as ex:
res = list(ex.map(lambda _: one(proxy_url, url, marker), range(n)))
oks = [r for r in res if r[0]]
lat = sorted(r[1] for r in res)
return {
"success_rate": len(oks) / n,
"median_s": statistics.median(lat),
"p95_s": lat[int(n * 0.95)],
"avg_bytes_ok": sum(r[2] for r in oks) / max(len(oks), 1),
"errors": collections.Counter(r[3] for r in res if not r[0]).most_common(5),
}Step 4: Test IP diversity and geography
Request an IP-info endpoint a few hundred times through each provider and count unique IPs, /24 subnets and ASNs, and check the country and city match your targeting. See proxy pool size.
Step 5: Test sticky sessions
Open a sticky session and poll an IP echo endpoint every 30 seconds. Record how long the IP holds before it changes or the session errors. Repeat 10 times and take the median. See sticky vs rotating sessions.
Step 6: Test speed properly
Measure from the server where you'll run in production, not your laptop. Separate connection time from time-to-first-byte where possible. See proxy speed test.
Proxy tip: When you shortlist providers, include at least one with flexible pay-as-you-go pricing. Geonode fits that role: per-GB residential traffic, static ISP and datacenter options, and scraping APIs if you'd rather pay per request. Read our Geonode proxies guide for details.
Step 7: Calculate cost per success
per-GB: cost per 1,000 successes = (total bytes ÷ 1e9 × price per GB) ÷ successes × 1,000
per-IP: cost per 1,000 successes = (IPs needed × price per IP ÷ monthly successes) × 1,000Step 8: Score and decide
Weight the metrics by what matters for your use case. For scraping, success rate and cost per success dominate. For sneakers, speed and success on the specific site dominate. For accounts, stability and IP quality dominate.
Testing tips
- Test at the time of day you'll run in production; residential pools vary by time zone.
- Don't test only on easy targets; include your hardest.
- Re-test after a week. Some providers perform well initially and degrade.
- Keep raw results so you can re-test later and compare.
A one-day testing plan
| Time | Task |
|---|---|
| Morning | Sign up for trials with 2 to 3 providers; set up sub-users and credentials |
| Late morning | Run IP diversity and geo checks (200 requests each) |
| Midday | Run target tests: 500 requests per provider per target |
| Afternoon | Run sticky session hold tests (10 sessions each) |
| Late afternoon | Repeat target tests at your production time of day if different |
| End of day | Calculate cost per success and score providers |
Scoring template
| Metric | Weight | Provider A | Provider B | Provider C |
|---|---|---|---|---|
| Success rate on hardest target | 30% | |||
| Cost per 1,000 successes | 25% | |||
| p95 latency | 15% | |||
| Session stability | 10% | |||
| IP diversity / geo accuracy | 10% | |||
| Support responsiveness | 10% |
Adjust weights to your use case. For sneakers, raise latency and site-specific success; for accounts, raise stability and IP cleanliness.
Common testing mistakes
- Testing only against an IP echo service. That shows connectivity, not success on your target.
- Different code per provider. Small differences in headers or concurrency skew results.
- Too few requests. A few dozen requests can mislead; aim for hundreds.
- Testing at the wrong time. Residential pools vary by hour.
- Ignoring bytes per request. Two providers with equal success can have different costs if one triggers heavier block pages.
- Forgetting soft blocks. Validate content, not status codes. See avoiding IP bans when scraping.
After you choose
Keep your test harness. Re-run it monthly or when success rates dip, and before renewing annual plans. It's also the fastest way to evaluate a new provider later. See how to choose a proxy provider.
Keeping test traffic polite
A proxy test shouldn't turn into a load test on somebody else's website. A few rules keep evaluations fair to the sites involved and, as a bonus, give more realistic results:
- Use the lightest page that answers the question. For connectivity, IP checks and speed, use echo services or a server you control. Save real target pages for the success-rate test.
- Cap the rate per target. A few requests per second across the whole test is plenty to measure block rates on most sites.
- Spread tests over hours rather than firing everything in one burst. Production traffic isn't bursty either.
- Respect robots.txt and terms for the target pages you test, just as you would in production.
- Stop on clear signals. If a target returns 429 with a
Retry-Afterheader, wait. Don't "test through it". - Do throughput tests on your own files. Large downloads belong on servers you control.
Polite tests also protect your trial: hammering a target can get a provider's IPs flagged in a way that makes them look worse than they are. For the ethics behind this, see ethical web scraping; for pacing, rate limiting and proxies; and for throughput testing done properly, how to test proxy speed.
FAQ
How many requests do I need for a meaningful test?
A few hundred per provider per target gives a reasonable picture; a thousand is better.
Can I test sneaker proxies the same way?
Partly. Use your bot's proxy tester against the actual retailer, and test speed from your bot server. See sneaker proxy speed.
Editorial note: Proxy providers change their pools, features and prices often, so treat any figures here as typical ranges at the time of writing and confirm current terms with the provider before you buy.