Understanding Proxy Performance Bottlenecks
Every proxied request has three latency components:
- Client → Proxy RTT: Time from your machine to the proxy server. Minimize by using a local or nearby proxy server. ProxifyPRO runs locally — essentially zero latency to the proxy.
- Proxy → Target RTT: Network path from proxy egress to target server. Depends on proxy geography and target location. Fixed for a given proxy.
- Protocol overhead: TCP handshake (1 RTT), TLS handshake (1-2 RTT). Reducible via connection reuse.
For mobile proxies: cellular network adds 20-100ms vs fiber. But this is the egress latency — what the target site experiences. Scraping latency is dominated by target site response time (typically 200-1000ms), making the mobile overhead irrelevant in practice.
Connection Pooling
TCP connections are expensive to establish: 3-way handshake (1 RTT), TLS handshake (1-2 RTT), HTTP request/response, connection close. That's 3-4 round trips per request. With connection pooling, the TCP+TLS overhead is paid once, then multiple HTTP requests reuse the same connection via HTTP keep-alive.
import requests
from requests.adapters import HTTPAdapter
# Session = connection pool
session = requests.Session()
adapter = HTTPAdapter(
pool_connections=20, # Max simultaneous destinations
pool_maxsize=50, # Max connections per destination
max_retries=3
)
session.mount('http://', adapter)
session.mount('https://', adapter)
# All requests through session reuse connections
proxies = {"http": "http://user:pass@proxy:8080",
"https": "http://user:pass@proxy:8080"}
for url in urls:
r = session.get(url, proxies=proxies)
# Connection reused for same destination
Performance impact: first request to a domain takes 300-500ms (handshake overhead). Subsequent requests take 50-150ms (data only). At 100 requests to the same domain, connection pooling saves 30-45 seconds total.
HTTP/2 Multiplexing
HTTP/1.1 is sequential — one request at a time per connection. HTTP/2 multiplexes multiple requests over one TCP connection simultaneously. For scraping: instead of 100 sequential requests (100 × RTT), HTTP/2 sends all 100 over one connection — dramatically reducing total time.
Support check: if target server supports HTTP/2, use httpx (Python) or h2 library instead of requests:
import httpx
import asyncio
async def scrape_batch(urls, proxy):
async with httpx.AsyncClient(
proxies=proxy,
http2=True # Enable HTTP/2
) as client:
tasks = [client.get(url) for url in urls]
results = await asyncio.gather(*tasks)
return results
# 100 requests over HTTP/2 ≈ time of 1-5 requests over HTTP/1.1
Caching Strategies
The fastest request is the one you don't make. Cache at multiple levels:
- DNS caching: Cache DNS resolutions (TTL-based). Avoids DNS lookup overhead on every connection.
- HTTP conditional requests: Send
If-Modified-SinceandIf-None-Matchheaders. Server returns 304 (no body) if unchanged — saves bandwidth, counts as successful check. - Content cache: SQLite or Redis: URL → (content, timestamp). Before fetching, check if content exists and is fresh enough for your use case.
- Negative cache: Cache 404s and 403s. Don't retry URLs that returned client errors unless content changes.
Hardware Optimization for ProxifyPRO
For high-throughput proxy setups (20+ dongles, 1000+ concurrent requests):
- USB controller quality: Cheap USB hubs share bandwidth across all ports. Use powered hubs with dedicated USB controllers per port. Industrial Cambrionix hubs provide this.
- RAM: Each proxy connection uses ~128KB buffer. 1000 concurrent = 128MB just for buffers. Add OS overhead: 8GB RAM handles ~10K concurrent comfortably.
- CPU: 3proxy is highly optimized C — minimal CPU even at high concurrency. Node.js orchestration layer: more CPU intensive per connection. i5-class CPU handles 5000+ concurrent proxy connections.
- SSD vs HDD: For logging and SQLite: SSD required. HDD latency (5-10ms per write) becomes a bottleneck at 1000+ requests/second logged.
Benchmarking Your Proxy Setup
| Metric | Target Value | Tool |
|---|---|---|
| Latency p50 | <200ms | wrk, hey |
| Latency p95 | <500ms | wrk, hey |
| Throughput | >100 req/sec/dongle | wrk |
| Connection reuse % | >90% | Wireshark, tcpdump |
| Error rate | <2% | Application metrics |
| Memory per connection | <200KB | pmap, /proc/meminfo |
# Benchmark with wrk (HTTP load testing) wrk -t4 -c100 -d30s --script=proxy_script.lua http://proxy-server:8080 # Custom benchmark for proxy-specific metrics: hey -n 1000 -c 50 -x http://user:pass@proxy:8080 https://httpbin.org/ip
Mobile Proxy Performance Characteristics
Mobile proxies have different performance profiles than datacenter:
- Latency: 50-200ms base (carrier network overhead). Acceptable for scraping, problematic for real-time applications.
- Throughput: 4G LTE: 5-50 Mbps. 5G: 50-500 Mbps. Usually sufficient for scraping (target site response is the bottleneck).
- Variability: Signal strength affects latency and throughput. Strong signal (-50 to -70 dBm): consistent. Weak signal (-90+ dBm): variable, drops.
- Rotation time: PDP context reset: 10-20 seconds. Natural CGNAT rotation: continuous. Plan rotation frequency around your throughput needs.
ProxifyPRO tracks signal strength per dongle in real time. If a dongle drops below -85 dBm (weak signal), it triggers an alert and can be auto-paused. Position dongles near windows for optimal signal. External antennas (SMA connector compatible models) improve signal by 10-15 dBm in marginal signal areas.