Proxy bandwidth billing is one of those areas where the number on your dashboard and the traffic you actually used can quietly diverge. A provider that rounds up to the nearest MB per request, counts TLS handshake overhead as metered traffic, or charges for failed and timed-out requests will show higher consumption than your actual payload transfer — and that gap compounds at scale.
This guide covers how to measure real proxy throughput and verify billing accuracy using command-line tools, Python, and a no-code online checker. The benchmark table at the end gives you a reference point across provider tiers so you know what numbers to expect before you start testing.
What "Bandwidth" Actually Means on a Metered Proxy Plan
On a per-GB proxy plan, bandwidth refers to the volume of data transferred through the proxy tunnel. But what counts toward that volume varies by provider, and the differences are significant enough to affect your cost per operation by 15–30% in some cases.
The main billing variables to watch for:
Payload-only billing counts the bytes of the actual HTTP response body — the content you requested. This is the most accurate method from the user's perspective.
Full request/response billing counts headers, handshake bytes, and protocol overhead in addition to the response body. A 1 MB payload request might consume 1.05–1.15 MB of metered bandwidth depending on TLS negotiation and header size.
Rounding behavior adds up quickly at scale. Rounding each request up to the nearest KB adds about 0.5 KB per request on average. At 100,000 requests per day, that's 50 MB of phantom consumption daily.
Failed request billing is the most expensive variable. If a proxy request fails — timeout, connection reset, 407 authentication error — some providers still charge for the attempted data transfer. If your failure rate is 5% and you're paying for those failures, your effective cost per successful request is 5% higher than the rate card suggests.
The only way to know how your provider bills is to measure it directly: pull a known payload size through the proxy and compare what you received against what your dashboard reports.
CLI Testing: curl Bandwidth Verification
The fastest measurement is a single curl command with explicit output formatting:
Pull a precisely sized payload through your proxy
Replace user, pass, host, port with your credentials
curl -x http://user:pass@host:port \
-o /dev/null \
--silent \
-w "status: %{http_code}\nbytes_received: %{size_download}\ntime_total: %{time_total}s\nspeed_avg: %{speed_download} B/s\n" \
https://httpbin.org/bytes/10485760
Expected output for a clean 10MB transfer:
status: 200
bytes_received: 10485760
time_total: 3.241s
speed_avg: 3234567 B/s
The critical field is size_download — this is the exact number of bytes your client received. Compare it against the expected payload size (10,485,760 bytes for a 10 MB payload). If they match, the proxy delivered the full payload without truncation or modification.
After running this, check your provider's dashboard and note the bandwidth consumed for this session. If the dashboard shows 11.2 MB consumed for a 10 MB payload pull, the delta represents overhead billing — either protocol overhead, rounding, or both.
Batch test across multiple proxy IPs:
!/bin/bash
Test bandwidth accuracy across a proxy pool
PAYLOAD_MB=50
PAYLOAD_BYTES=$((PAYLOAD_MB * 1024 * 1024))
URL="https://httpbin.org/bytes/${PAYLOAD_BYTES}"
PROXIES=(
"http://user:pass@host1:port"
"http://user:pass@host2:port"
"http://user:pass@host3:port"
)
echo "proxy,status,bytes_received,expected_bytes,time_s,speed_bps"
for PROXY in "${PROXIES[@]}"; do
RESULT=$(curl -x "$PROXY" \
-o /dev/null \
--silent \
--max-time 60 \
-w "%{http_code},%{size_download},${PAYLOAD_BYTES},%{time_total},%{speed_download}" \
"$URL" 2>/dev/null)
echo "$PROXY,$RESULT"
done
Run this across 5–10 IPs from your pool and compare the bytes_received column against expected_bytes. Consistent shortfalls indicate proxy-side content modification. Consistent overages in your dashboard indicate overhead billing.
Python: Throughput and Billing Verification
For integrating bandwidth testing into a workflow or running it on a schedule:
import requests
import time
from dataclasses import dataclass, field
from typing import Optional
@dataclass
class BandwidthResult:
proxy: str
status_code: Optional[int] = None
bytes_received: int = 0
expected_bytes: int = 0
elapsed_s: float = 0.0
throughput_mbps: float = 0.0
delta_pct: float = 0.0
error: Optional[str] = None
def measure_proxy_bandwidth(
proxy_url: str,
payload_mb: int = 50,
timeout: int = 60
) -> BandwidthResult:
payload_bytes = payload_mb * 1024 * 1024
url = f"https://httpbin.org/bytes/{payload_bytes}"
proxies = {"http": proxy_url, "https": proxy_url}
result = BandwidthResult(proxy=proxy_url, expected_bytes=payload_bytes)
start = time.perf_counter()
try:
resp = requests.get(url, proxies=proxies, stream=True, timeout=timeout)
result.status_code = resp.status_code
received = 0
for chunk in resp.iter_content(chunk_size=65536):
received += len(chunk)
result.elapsed_s = round(time.perf_counter() - start, 3)
result.bytes_received = received
result.throughput_mbps = round(
(received * 8) / (result.elapsed_s * 1_000_000), 2
)
result.delta_pct = round(
(payload_bytes - received) / payload_bytes * 100, 2
)
except requests.exceptions.Timeout:
result.error = "timeout"
except Exception as e:
result.error = str(e)
return result
Run against your proxy list
proxies_to_test = [
"http://user:pass@host1:port",
"http://user:pass@host2:port",
"http://user:pass@host3:port",
]
print(f"{'Proxy':<35} {'Status':>6} {'Received MB':>11} {'Speed Mbps':>10} {'Delta %':>8}")
print("-" * 75)
for proxy_url in proxies_to_test:
r = measure_proxy_bandwidth(proxy_url, payload_mb=50)
if r.error:
print(f"{proxy_url:<35} {'ERR':>6} {r.error}")
else:
received_mb = round(r.bytes_received / (1024 * 1024), 2)
print(
f"{proxy_url:<35} {r.status_code:>6} "
f"{received_mb:>11} {r.throughput_mbps:>10} {r.delta_pct:>8}"
)
The delta_pct field is your billing accuracy signal. A value of 0.0 means you received exactly the payload you requested. A negative value (say, -2.1) means 2.1% less data arrived than expected, which could indicate proxy-side content stripping or compression. After running the test, compare total bytes_received across your session against what your provider's dashboard shows for the same window.
Using the NodeMaven Proxy Bandwidth Checker
For a no-code version of the same measurement, the NodeMaven Proxy Bandwidth Checker runs a payload transfer through your proxy and reports HTTP status, elapsed time, bytes received, and expected bandwidth side by side in the browser. Paste your proxy in host:port:user:password format, select payload size (up to 500 MB), and run. No SDK, no extension, no setup.
The tool works with any HTTP or SOCKS5 proxy — not just NodeMaven proxies — which makes it useful as a neutral verification step in any proxy workflow. The side-by-side display of bytes received vs expected bandwidth is specifically designed to surface the billing accuracy question: if your provider's dashboard shows more consumption than the checker measured on the same payload, the delta is overhead or rounding you're being charged for.
Practical uses:
Baseline a new provider before committing to a larger plan
Verify billing accuracy after noticing dashboard consumption higher than expected
Compare throughput across proxy types (residential vs mobile vs ISP) on your specific target
Pre-flight check before a bandwidth-intensive scraping run
Benchmark Reference: What to Expect by Proxy Type
The numbers below represent typical performance in 2026 on a clean payload endpoint. Real-world throughput on actual scraping targets will be lower due to target-side latency, JavaScript rendering overhead, and retry traffic. For residential proxy performance specifically, results depend heavily on IP quality — residential proxies with pre-filtered IPs consistently sit at the higher end of the throughput range compared to unfiltered pools.
For operations where throughput consistency matters more than pool size — long-running sessions, account management, tools that flag IP changes — ISP proxies typically deliver the most stable bandwidth numbers of any proxy type, as the table above reflects.
Provider Comparison: Bandwidth Billing Behavior
Not all providers are transparent about what counts toward metered bandwidth. Based on publicly documented billing policies and community testing in 2026:
The practical difference between payload-only billing and full request/response billing with per-KB rounding is roughly 8–15% on typical scraping workloads with small-to-medium response sizes. On large payload transfers (images, files, bulk data), the difference narrows. On high-frequency small-request patterns (API calls, status checks), the difference widens.
Interpreting Your Results
After running a benchmark session, you'll have three numbers: measured bytes received, expected payload bytes, and dashboard-reported consumption.
Measured ≈ expected, dashboard ≈ expected: Clean billing. What you pulled is what you were charged for.
Measured ≈ expected, dashboard significantly higher: Overhead billing. The proxy is charging for protocol and handshake bytes beyond the payload. Calculate the ratio across multiple tests to determine the effective markup.
Measured < expected: The proxy is modifying content — truncating responses, stripping content, or applying compression that reduces payload size. This is unusual on quality proxy infrastructure and worth raising with support.
Measured < expected on failed requests, dashboard shows consumption: The provider is billing for failed transfers. Run a test where you intentionally hit a timeout or connection reset and check whether the dashboard records bandwidth for the failed attempt.
Building Bandwidth Testing Into Your Workflow
For operations running daily, a lightweight pre-flight bandwidth check adds minimal overhead and catches degradation before it affects a production run:
def proxy_bandwidth_preflight(
proxy_url: str,
min_throughput_mbps: float = 2.0,
payload_mb: int = 10
) -> bool:
"""Returns True if proxy meets minimum throughput threshold."""
result = measure_proxy_bandwidth(proxy_url, payload_mb=payload_mb)
if result.error:
return False
return result.throughput_mbps >= min_throughput_mbps and result.status_code == 200
Example: filter a proxy list to only passing IPs before a scraping run
proxy_list = ["http://user:pass@host1:port", "http://user:pass@host2:port"]
healthy_proxies = [p for p in proxy_list if proxy_bandwidth_preflight(p)]
print(f"{len(healthy_proxies)}/{len(proxy_list)} proxies passed pre-flight check")
Set the min_throughput_mbps threshold based on your workflow's requirements — scraping static pages needs less throughput than rendering JavaScript-heavy sites. Run the check from the same server your scraping jobs run from, since network path to the proxy affects results as much as the proxy itself.
Bandwidth testing is one of the few proxy workflow steps that pays for itself immediately: a 30-second pre-flight check that catches a degraded proxy pool before a 6-hour scraping run is worth far more than the bandwidth it consumes.


Top comments (0)