A proxy's speed is not one number: it is latency (how long until the first byte), throughput (how fast the bytes arrive), and success rate (how often you get a usable response at all) — each of which varies by hour, by target and by exit IP. A single test at one moment tells you almost nothing, which is why provider marketing numbers and one-off reviews are so easy to produce and so hard to act on. This is the method we use for our own rankings: what to measure, how, how often, and how to summarise it so the result means something.

The four numbers

MetricWhat it answersHow to get itTypical good value
Latency (TTFB)How long each request waits before data startscurl -w %{time_starttransfer} on a small resourceDatacenter: +10–50 ms over direct; residential/mobile: +80–300 ms
ThroughputHow fast bulk data movesTime a fixed-size download (1–10 MB)Datacenter: near line speed; residential: 5–50 Mbit/s; mobile: 5–30 Mbit/s
Success rateHow often a request completes with a real 2xxCount outcomes over many requests>98% on neutral targets; lower on protected ones is the target's doing
UptimeHow often the proxy is reachable at allPeriodic connectivity probe over days>99.5% for datacenter/ISP; rotating pools mask individual outages

Reports that give one “speed” figure are usually reporting throughput on a large download from a datacenter proxy at a quiet hour — the most flattering combination possible.

Principles before commands

  1. Measure the difference, not the absolute. Always run the same request direct and through the proxy, back to back, and report the delta. Your own connection's variability is otherwise mixed into the proxy's.
  2. Same target, always. Use a small, fast, stable endpoint that does not rate-limit — a static file on a major CDN, or your own server. Never benchmark against the site you intend to scrape; its anti-bot response is a different measurement.
  3. Many samples, spread over time. At least 20 requests per run; runs at several hours of the day and across a week. Proxies are shared infrastructure and load follows business hours in the provider's and the exit IPs' regions.
  4. Report percentiles, not averages. One 30-second timeout destroys a mean. Median (p50) tells you the typical experience; p95 tells you the bad-day experience; both matter more than the average.
  5. Warm up. Discard the first request of each run — DNS and TLS session setup make it slower than the rest.
  6. Change one thing at a time. Comparing provider A's datacenter to provider B's residential compares types, not providers.

Latency with curl

# direct
curl -o /dev/null -s -w "dns %{time_namelookup}  connect %{time_connect}  tls %{time_appconnect}  ttfb %{time_starttransfer}  total %{time_total}\n" \
     https://cdn.example.com/1kb.txt

# proxied
curl -x http://user:pass@proxy.example.com:8080 -o /dev/null -s \
     -w "connect %{time_connect}  tls %{time_appconnect}  ttfb %{time_starttransfer}  total %{time_total}\n" \
     https://cdn.example.com/1kb.txt

Through a proxy, time_connect is the time to reach the proxy; the destination's connect and TLS happen inside the tunnel and land in time_appconnect/time_starttransfer. The number to compare is ttfb: proxied minus direct is the proxy's added latency. Loop it:

for i in $(seq 1 20); do
  curl -x http://user:pass@proxy.example.com:8080 -o /dev/null -s -w "%{time_starttransfer}\n" https://cdn.example.com/1kb.txt
done | sort -n | awk '{a[NR]=$1} END{print "p50", a[int(NR*0.5)], "p95", a[int(NR*0.95)]}'

Throughput

curl -x http://user:pass@proxy.example.com:8080 -o /dev/null -s -w "%{speed_download} bytes/s  %{size_download} bytes  %{time_total}s\n" \
     https://cdn.example.com/5mb.bin

Use a file large enough that connection setup is a small fraction (5–10 MB), small enough not to burn a per-GB residential allowance across many runs. On rotating pools throughput varies with the exit host's connection; run enough samples to see the distribution, and remember that on per-GB plans throughput also determines how fast you spend money.

Success rate

Every request ends in one of: a 2xx with a body of the expected size; a 4xx/5xx from the target; a proxy error (407, connection refused, timeout); or a challenge page (CAPTCHA/interstitial) with a 200 status — the last is the one naive counters miss, so check the body, not just the code. In Python:

import requests, time, statistics as st

PROXY = {"https": "http://user:pass@proxy.example.com:8080"}
URL, N = "https://cdn.example.com/1kb.txt", 50
lat, outcomes = [], {"ok": 0, "http_err": 0, "proxy_err": 0, "timeout": 0, "challenge": 0}

for i in range(N):
    t = time.perf_counter()
    try:
        r = requests.get(URL, proxies=PROXY, timeout=15)
        dt = time.perf_counter() - t
        if r.status_code == 200 and len(r.content) > 500 and b"captcha" not in r.content.lower():
            outcomes["ok"] += 1; lat.append(dt)
        elif r.status_code == 200:
            outcomes["challenge"] += 1
        else:
            outcomes["http_err"] += 1
    except requests.exceptions.ProxyError:
        outcomes["proxy_err"] += 1
    except requests.exceptions.Timeout:
        outcomes["timeout"] += 1
    time.sleep(0.5)

lat.sort()
print(outcomes, "success %.1f%%" % (100 * outcomes["ok"] / N))
if lat: print("p50 %.3fs  p95 %.3fs" % (lat[len(lat)//2], lat[int(len(lat)*0.95)]))

Separate proxy failures (407, connect errors, timeouts to the proxy) from target failures (403, 429, challenges). The first are the provider's problem; the second are about the IP's reputation on that target and belong to a different test — see how anti-bot systems score requests.

Uptime

Uptime is success rate over calendar time. Schedule a lightweight probe — the latency command above, or a bare CONNECT — every 5–15 minutes for at least a week, log the outcome with a timestamp, and compute the fraction of probes that succeeded. Two subtleties:

  • Rotating pools hide outages. If one exit dies you get another; the gateway itself is what has uptime. Probe the gateway, and separately track how often the assigned IP changes when you asked for a sticky session — an unexpected change is a soft outage.
  • Static IPs (datacenter, ISP) are what “99.9%” is usually claimed for. 99.9% is 43 minutes of downtime per month; 99.5% is 3.6 hours. Both are easy to distinguish from a week of 15-minute probes.

Scheduling the runs

A minimal but meaningful schedule: latency + success (20–50 requests) at 03:00, 09:00, 14:00 and 20:00 in the exit IPs' local time, every day for seven days; throughput once per run; a connectivity probe every 15 minutes throughout. That is a few hundred kilobytes a day per proxy for latency and a few tens of megabytes for throughput — affordable even on per-GB plans if you use a small file. Run it from a machine that stays on (a small VPS is ideal) with cron, and write one CSV line per request. Our published rankings — for example the speed ranking and the reliability ranking — are built from exactly this kind of week-long series, not from a single afternoon.

Reading the results

  • p50 latency close to the type's norm and p95 within ~3× p50: healthy. A p95 many times the p50 means intermittent congestion — the provider is oversubscribed at peak.
  • Success rate under ~97% on a neutral target from proxy-side errors: infrastructure problem, not yours.
  • Daytime much worse than night: shared capacity; ask about dedicated options or accept it in scheduling.
  • Great numbers on datacenter, poor on residential from the same provider: normal — different products; compare residential to residential.
  • Uptime below the claim: you now have a log to show support, which is worth more than a complaint.

Finally, keep the type in mind. Residential and mobile proxies are slower by construction — the traffic really traverses a home line or a cell tower — and buying them for speed is a category error; see the proxy types comparison. Measure them against their own class and against what your task actually needs. Note too that a proxied connection runs HTTP/2, not HTTP/3, so compare like with like when the direct baseline is on a QUIC-enabled site (details).

Frequently asked questions

How do I test proxy speed?

Request the same small resource directly and through the proxy, many times, at several times of day; compare time-to-first-byte (latency) and, separately, time a fixed-size download (throughput). Report medians and 95th percentiles, not averages.

What is a good proxy latency?

Relative to a direct connection: datacenter proxies add tens of milliseconds; residential and mobile add roughly 80–300 ms because traffic passes through a consumer connection. Judge each type against its own norm.

How do I check proxy uptime?

Probe it on a schedule (every 5–15 minutes) for at least a week, log each outcome, and compute the fraction of successful probes. For rotating pools probe the gateway; for static IPs probe the IP itself.

Why do my results differ from the provider's claims?

Claims are usually best-case: datacenter product, quiet hour, large download, single sample. Your measurement includes peak hours, the specific exit IPs you receive, and percentiles. Yours is the number that predicts your experience.

Should I benchmark against the site I want to scrape?

Not for speed. Its anti-bot layer will add challenges and blocks that measure IP reputation, not proxy performance. Use a neutral static resource for speed and run reputation tests separately.

How many samples do I need?

At least 20 per run to get a stable median, several runs a day across a week to see time-of-day and day-of-week effects. Uptime needs the week regardless.