How to Build a Proxy Rotation System in Python
By Marcus Reiner · 2026-07-05 · 10 min read · Engineering
A production-grade proxy rotation system in ~150 lines of Python. Health checks, ban detection, weighted scoring.
Architecture
A rotation system has four components: pool loader (from provider API or static list), health checker (background pings), request router (picks best IP per call), failure handler (penalizes/evicts bad IPs).
Scoring model
Each IP carries a score: starts at 100, -10 on 4xx/5xx, -5 on slow response (>5s), +1 on clean success. Evict at score <0. Restore evicted IPs after 30-min cooldown.
Code sketch
```python import time, random, requests from collections import defaultdict class ProxyPool: def __init__(self, proxies): self.scores = defaultdict(lambda: 100) self.cooldown_until = {} self.proxies = proxies def pick(self): now = time.time() live = [p for p in self.proxies if self.scores[p] > 0 and self.cooldown_until.get(p, 0) < now] weights = [self.scores[p] for p in live] return random.choices(live, weights=weights, k=1)[0] def report(self, p, ok, latency): if ok and latency < 5: self.scores[p] = min(100, self.scores[p] + 1) elif not ok: self.scores[p] -= 10 if self.scores[p] <= 0: self.cooldown_until[p] = time.time() + 1800 ```
Skip this for rotating-endpoint providers
If your provider exposes a rotating endpoint (Decodo, Bright Data, IPRoyal, Oxylabs, SOAX all do), the provider runs this logic for you — and at higher quality. Build your own only when you have a static IP list.
Monitoring
Export Prometheus metrics: requests by status, p50/p99 latency, pool size, evictions per minute. Without monitoring you won't notice when 30% of your pool silently dies.
FAQ
Do I need async?
For >50 req/s, yes — use httpx or aiohttp. For lower throughput, threaded requests is simpler and fast enough.