A proxy list is a claim, not a fact. Before you build anything on top of one, you need to know which entries are alive, which leak your real address, how fast each one is, and whether it exits where it claims. This guide covers all four, with code.
What to test
- Liveness. Does it complete a request at all, within a sane timeout?
- Anonymity. Does it forward headers that reveal your origin address?
- Speed. Time to first byte, measured consistently against one endpoint.
- Geolocation. Does the exit country match what the list claims?
Anonymity levels
| Level | Behaviour | Safe for research? |
|---|---|---|
| Transparent | Forwards your IP in X-Forwarded-For | No |
| Anonymous | Hides your IP but identifies itself as a proxy | Sometimes |
| Elite | No proxy headers, no origin disclosure | Yes |
Transparent proxies are worse than useless for most work: you take the latency penalty and still disclose your address. Our guide to anonymity levels goes deeper.
A concurrent checker
import concurrent.futures as cf
import requests, time
TEST_URL = "https://api.ipify.org?format=json"
TIMEOUT = 8
def check(proxy_url):
proxies = {"http": proxy_url, "https": proxy_url}
start = time.perf_counter()
try:
r = requests.get(TEST_URL, proxies=proxies, timeout=TIMEOUT)
r.raise_for_status()
return {
"proxy": proxy_url,
"alive": True,
"exit_ip": r.json().get("ip"),
"ms": round((time.perf_counter() - start) * 1000),
}
except Exception as exc:
return {"proxy": proxy_url, "alive": False, "error": type(exc).__name__}
proxies_to_test = ["http://198.51.100.10:8080", "http://203.0.113.7:3128"]
with cf.ThreadPoolExecutor(max_workers=50) as pool:
for result in pool.map(check, proxies_to_test):
print(result)Fifty workers is a reasonable starting point. The bottleneck is waiting on the network, not CPU, so threads are the right tool here. Raise it if your list is large and your machine is idle.
Checking for leaks
To detect a transparent proxy, request an endpoint that echoes the headers it received and look for X-Forwarded-For, Via or X-Real-IP containing your own address. Our HTTP header checker shows exactly what arrives at the far end, which is the fastest way to confirm a single proxy by hand before you script anything.
Interpreting the results
Free lists typically show high failure rates and short lifetimes — entries that worked an hour ago are frequently dead now — which is why anything built on them needs continuous re-testing rather than a one-off validation. If you are spending real engineering time maintaining a checker for a free list, compare that against rotating datacenter at $1.00/GB, where liveness is not your problem.
Test it by hand first
Before writing any of this, paste a single proxy into our proxy checker. It reports liveness, anonymity level, speed and geolocation in one step, which is usually enough to tell you whether a list is worth scripting against at all.
Frequently Asked Questions
How do I know if a proxy is anonymous?
Request an endpoint that echoes received headers and look for X-Forwarded-For, Via or X-Real-IP containing your real address. If they are present, the proxy is transparent and is disclosing you.
How many proxies can I test at once?
Around 50 concurrent workers is a sensible start. The work is network-bound rather than CPU-bound, so threads scale well; raise it for larger lists.
Why do so many free proxies fail?
Free proxies are typically short-lived, overloaded and often transparent. High failure rates and constant churn are normal, which is why they need continuous re-validation.
What is a good response time?
Compare candidates against each other on the same endpoint rather than chasing an absolute number, since your own location affects every measurement.
Related: proxy checker · proxy pricing · all eight products.