Client-side rotation
ISP IPs are permanently stable — there's no session parameter and no gateway rotation. If you want different IPs across requests, your client picks them. This page documents the common patterns.
Round-robin
The simplest pattern: cycle through the list in order.
import itertools, requests
with open("isp.txt") as f:
lines = [l.strip() for l in f if l.strip()]
cycle = itertools.cycle(lines)
def get(url):
ip, port, user, password = next(cycle).split(":", 3)
proxy = f"http://{user}:{password}@{ip}:{port}"
return requests.get(url, proxies={"http": proxy, "https": proxy}, timeout=30)Pros: trivial. Cons: failed IPs keep getting picked.
Round-robin + health tracking
Track failures and skip dead IPs for a cool-down window:
Sticky-per-task
If your unit of work needs a stable IP (login flow, multi-step purchase), pin one IP per task:
Consistent hashing means restarts and re-runs of the same task_id hit the same IP.
Concurrency caps
Each ISP IP can handle high throughput (1 Gbps+), but most target sites will rate-limit you per IP. A reasonable starting point: max 5 concurrent requests per IP to a single target site. Sharded across the batch, this scales linearly.
Coordinating across processes
If multiple workers share one batch, use a shared store (Redis, etcd) to coordinate rotation and health tracking. A simple Redis-backed pool:
For health tracking, use a sorted set keyed on cooldown_until and skip entries above now().
When not to rotate
If your use case is account-bound (logged-in scraping, posting, monitoring a logged-in dashboard), do not rotate. Pin one IP per account. The whole reason to use ISP is IP stability — rotating defeats it.
Tools that handle rotation for you
Antidetect browsers (AdsPower, Multilogin, GoLogin) — assign a different ISP IP per browser profile
Proxifier — round-robin across imported list at the OS level
Scrapy + scrapy-rotating-proxies — middleware reads a list and rotates
Apify SDK proxy configuration — handles rotation automatically when given a list
For most production stacks, your scraper framework's built-in proxy rotator is enough. The code above is for when you need custom logic.
Last updated
Was this helpful?