A proxy speed test is two numbers, not one, and the fastest free way to get both is already on your machine. curl's built-in timers tell you the latency (how long a request takes to come back) and its download meter tells you the throughput (how much data the connection moves per second). A small Python loop turns a single reading into a reliable median, and the only real trick is testing from the region your job runs in, against a target near where you will actually send traffic. This guide covers all of it, every command copy-paste runnable.
We run a proxy network and a live proxy checker, so we watch people misjudge proxies constantly: a single lucky sample that looks fast, a number measured from the wrong continent, or a "slow proxy" that was really a slow target. The measurements below fix that, and none of them need a paid tool.
How do you test proxy speed?
Route a request through the proxy with curl and print its timing variables. This one line gives you the two numbers that matter most, the connect time and the total time, without downloading a byte of the page body:
curl -x http://IP:PORT -o /dev/null -s -w "connect:%{time_connect} total:%{time_total}\n" https://example.com
-x sets the proxy, -o /dev/null throws away the body, -s silences the progress bar, and -w prints the timers after the request finishes. Every number is in seconds. Run it a handful of times before you trust it.
Latency, throughput, and TTFB are three different numbers
People say "speed" and mean one of three things. Measuring the wrong one is how a proxy looks fine in a test and fails in production.
- Latency is round-trip time: send a request, count the milliseconds until an answer comes back. It is set mostly by physical distance, because signals in fiber travel at a finite speed, so a proxy on the far side of the planet is slow no matter how fast its hardware is. Latency is what matters for many small requests, where the per-request overhead dominates.
- Throughput is bandwidth: once the connection is open, how many bytes per second it moves. It is what matters for pulling large pages, files, or media, where the transfer dwarfs the setup.
- Time to first byte (TTFB) is the gap between finishing your request and the first byte of the response arriving. It folds in the proxy's own processing and the target's think time, and it is the single best "is this proxy responsive" signal. MDN defines it as the time between the request and the first byte of the response.
A proxy can be low-latency and low-throughput (quick to answer, slow to stream) or the reverse, so a real test reports both, and reads TTFB to tell a sluggish proxy from a sluggish target.
Time a proxy with curl, stage by stage
curl exposes the whole request lifecycle through -w (or --write-out), documented in the curl manual. Asking for each stage separately shows you exactly where the time goes:
curl -x http://IP:PORT -o /dev/null -s \
-w "dns:%{time_namelookup} connect:%{time_connect} tls:%{time_appconnect} ttfb:%{time_starttransfer} total:%{time_total}\n" \
https://example.com
Each variable is a cumulative stopwatch from the start of the request, so the differences between them are what you read:
| Variable | What it measures |
|---|---|
time_namelookup | DNS resolution finished |
time_connect | TCP connection to the proxy established |
time_appconnect | TLS handshake complete |
time_starttransfer | First byte arrived (this is the TTFB) |
time_total | Whole request, start to finish |
speed_download | Average throughput, in bytes per second |
DNS lookup
time_namelookup
TCP connect
time_connect, to the proxy
TLS handshake
time_appconnect
First byte
time_starttransfer, the TTFB
Transfer done
time_total
If time_connect is high, the hop to the proxy is slow or the proxy is overloaded. If time_starttransfer is much larger than time_connect, the proxy connected but then took a long time to start producing a response, which is the classic signature of a tired free proxy. To measure throughput instead of latency, download something with a known size and read the speed meter:
curl -x http://IP:PORT -o /dev/null -s -w "%{speed_download} bytes/s\n" https://your-target.example/largefile.bin
A small Python timer
When you want to test many proxies in a loop, or fold the numbers into a pipeline, time the request in code. The clean way is time.perf_counter around a single call:
import time
import requests
proxies = {"http": "http://203.0.113.7:8080", "https": "http://203.0.113.7:8080"}
start = time.perf_counter()
r = requests.get("https://example.com", proxies=proxies, timeout=(5, 30))
elapsed_ms = (time.perf_counter() - start) * 1000
print(f"status {r.status_code} {elapsed_ms:.0f} ms {len(r.content)} bytes")
One reading is noise. On a shared proxy the honest number is the median of several, which throws out the occasional stall without letting one lucky sample flatter a bad proxy:
import statistics
import time
import requests
proxies = {"http": "http://203.0.113.7:8080", "https": "http://203.0.113.7:8080"}
samples = []
for _ in range(10):
t = time.perf_counter()
requests.get("https://example.com", proxies=proxies, timeout=(5, 30))
samples.append((time.perf_counter() - t) * 1000)
print(f"median {statistics.median(samples):.0f} ms best {min(samples):.0f} ms")
requests also hands you a ready-made TTFB-like figure without any stopwatch: r.elapsed is a timedelta covering the time from sending the request to finishing the response headers. r.elapsed.total_seconds() is often all the latency signal you need. For the full picture of routing requests through proxies in Python, our Python requests guide covers sessions, rotation, and the timeout handling those loops depend on.
Test from the region that matters
A latency number is only meaningful next to the route it measured, and this is where most home-grown tests go wrong. When you test from your laptop, the figure includes your own hop to the proxy, a hop your production server in another data center may not share. And a proxy that answers a nearby test URL in 80 ms can be slow to the geographically distant site you actually scrape, because the proxy-to-target leg is part of the real cost.
Two rules keep the numbers honest. First, test from the same region your job will run in, so the client-to-proxy leg matches production. Second, test against a target close to where you will really send traffic, not just example.com, so the proxy-to-target leg is realistic too. This also explains a routine surprise: a mobile proxy usually tests slower and more variable than a datacenter IP, because the cellular leg genuinely adds latency, and that is the price of the trust it buys, not a broken proxy. The same distance logic is why persistent slowness on a nearby target is a red flag worth chasing in how to fix a 504 gateway timeout.
The fastest check: skip the scripting
Timing one proxy by hand is quick. Grading a batch is tedious, because "good" means fast and exiting where you expect and still anonymous, and stitching those checks together in a script is a chore. Our proxy checker runs the whole battery on a paste (exit IP, latency, real exit country, and anonymity grade) with no signup, from our own infrastructure rather than your laptop, so the latency figure is not skewed by your local connection. It is the fastest way to sort a handful of candidates before you commit one to a job, and it pairs naturally with the deeper liveness walkthrough in how to check if a proxy is working.
Whichever method you use, measure right before the proxy goes to work, take the median of several samples, and judge the number against the route rather than an absolute. When you need latency that stays low and predictable instead of the lottery of a free list, a residential proxy near your target, or a datacenter IP for lenient work, is what a stable number looks like. Grab a few free ones to practice these commands on from our free proxy list, which drops the dead instead of counting them, and time them yourself before you trust one.
Sources and further reading
- curl, "Manual: curl.1". The
-w/--write-outtiming variables (time_connect,time_starttransfer,time_total,speed_download) used throughout this guide. - MDN Web Docs, "Time to first byte (TTFB)". The definition of TTFB and where it sits in the request lifecycle.