Measuring IP Pool Size With a Script: Rotate, Log, Count
Published
Pool size is a question with a measurable answer. A line from Mobile Proxies US draws its addresses from one carrier's pool for one metro, and the number of distinct addresses you see over a period is a property of that pool and of how often you rotate. Rather than quote a figure, this page gives a script that measures it for your own line, explains what shapes the result, and sets expectations so the output does not surprise you: a regional pool, repeats within a day, and addresses that recur in the same /24 blocks.
What is being measured
Each rotation re-attaches the modem and the carrier assigns a public IPv4 address from its NAT pool for that gateway. The pool serves the whole region, not just the metro, so the addresses you see belong to a block the carrier uses for a wide area. Distinct addresses over N rotations is the metric; distinct /24 blocks is a useful second one because many sites and scoring services work at block granularity.
Pool size is not the same as address count on the carrier's side. You only observe the addresses your gateway hands out, and the gateway favours recently freed addresses. Expect a measurable number that is smaller than the carrier's total and larger than you can exhaust in a day.
The measurement script
The loop is simple: GET the rotation link, sleep, repeat. You do not need to write your own log, because the platform keeps one: GET /proxies/UUID/ip-history returns an audited record of every change, with old_public_ip, new_public_ip, status and created_at. The status is success, failed, submitted, or unchanged when a phone accepted the request and its IP did not change within 90 seconds. Count only the successes.
Choose the interval to match how you would actually rotate in production, and never below what the line allows: min_time_change_ip from the list call, plus the 1 to 2 minute cooldown on phone lines. A rotation inside either wait is refused with HTTP 400. Run it for 24 hours to catch the daily cycle: pools look different at 3 a.m. than at 7 p.m. when the cell is full of real phones.
import os, time, requests
BASE = "https://cp.mobileproxiesus.com/backend/api_v1"
H = {"x-api-key": os.environ["MPUS_API_KEY"]}
UUID = os.environ["LICENCE_UUID"]
lines = requests.get(f"{BASE}/proxies/my", headers=H, timeout=15).json()["proxyList"]
line = next(l for l in lines if l["uuid"] == UUID)
gap = max(line["min_time_change_ip"], 2) * 60 # phone lines also hold a 1-2 minute cooldown
end = time.time() + 86400
while time.time() < end:
r = requests.get(line["rotation_link"], timeout=30)
if r.status_code != 200:
print(r.status_code, r.json().get("message"))
time.sleep(gap)
Counting and reading the log
Page through the history with from and count (200 at most per page) until has_more is false, keep the rows whose status is success, and sort them by created_at. Analysis is three numbers: rows, distinct addresses, distinct /24 blocks. Also compute the gap between repeats: for each address that appears twice, how many rotations sat between the two sightings. A short median gap means a small active pool at that hour; a long one means a large pool or a gateway that cycles widely.
Plot distinct addresses against rotation count. The curve rises steeply at first and flattens as repeats appear. Where it flattens is the practical pool size for that gateway at that time of day. If it never flattens over a day, the pool is larger than a day's rotations can reveal, which is good news and also means you do not need to rotate faster.
import ipaddress, statistics
rows, start = [], 0
while True:
page = requests.get(f"{BASE}/proxies/{UUID}/ip-history", headers=H,
params={"from": start, "count": 200}, timeout=30).json()
rows += [h for h in page["histories"] if h["status"] == "success"]
start += len(page["histories"])
if not page["has_more"]:
break
rows.sort(key=lambda h: h["created_at"])
ips = [h["new_public_ip"] for h in rows]
blocks = {str(ipaddress.ip_network(ip + "/24", strict=False)) for ip in ips}
seen, gaps = {}, []
for i, ip in enumerate(ips):
if ip in seen:
gaps.append(i - seen[ip])
seen[ip] = i
print("rotations", len(ips), "distinct ips", len(set(ips)), "distinct /24", len(blocks))
print("median gap between repeats", statistics.median(gaps) if gaps else None)
What shapes the result
Carrier. T-Mobile tends to hand out addresses from a wide range per gateway and its addresses map to the metro itself; Verizon's pool is organised around regional hubs, so the addresses may geolocate a few hundred miles from the modem while the state stays right; AT&T sits between. None of this is fixed, carriers re-plan their NAT regularly, which is another reason to measure rather than quote.
Time of day. Busy hours mean more addresses in use by real phones and a gateway recycling faster. Network type: 4G and 5G lines on the same carrier in the same metro usually share a pool. Metro: eight metros means eight gateways' worth of pools, and a free move gives you another one to measure.
Repeats are normal
Seeing an address twice in a day is not a defect. A real handset in the same city sees exactly the same pool and the same repeats. Destination sites know this; a returning carrier address is the most ordinary event in their logs. The thing to avoid is a pattern a phone would never produce: an address change every ten seconds, or a session that changes address mid-login.
If the job genuinely needs more distinct addresses per hour than one gateway yields, the right tool is more lines in more metros or on more carriers, each with its own pool, driven from the same API key. The measurement script tells you exactly how many you need instead of guessing.
Reporting the figure honestly
When you write the number down for a colleague, write the conditions with it: carrier, metro, date, interval, hours observed. A pool size without conditions is a marketing number. With them it is an engineering measurement you can repeat next month and compare.
We do not publish pool sizes for this reason. The script above runs on any line, the API is included, and rotation is unlimited, so the measurement costs you one line-day and gives you the real figure for your own case.
Frequently asked
How many addresses will one line see in a day?
It depends on carrier, metro, hour and interval, which is why the page gives a script instead of a number. Run it for 24 hours at the interval you intend to use.
Why do addresses repeat?
The gateway serves a regional pool and favours recently freed addresses. Real phones see the same repeats. Destinations treat a returning carrier address as ordinary.
Does rotating faster give more addresses?
Only up to the point where the curve flattens. Past that you see repeats sooner. More lines in more metros or carriers add pools; faster rotation does not.
Do I have to log the addresses myself?
No. GET /proxies/UUID/ip-history is an audited record of every change on the line. Keep the rows with status success; page with from and count until has_more is false.
