Handling Repeat IPs in Automation: Finite Carrier Pools and Retries
If you drive NeonProxies from code, you will eventually see the same exit address twice in a row after a rotation call. That is not a failed rotation and it is not a bug in your worker. Every line sits on one SIM at one carrier gateway, and that gateway assigns addresses from a finite regional pool. Now and then the address it hands back is one your worker held a few minutes ago. A robust automation treats this as a normal event and handles it in a few lines of logic: rotate through the API, read the new address, compare it against a short memory of recent addresses, rotate again with a small retry budget, back off, and move the worker to another line if repeats persist. This guide walks through each step and the pool mechanics behind it.
Why a finite pool guarantees repeats
A carrier pool is the set of public addresses a gateway can assign to SIMs attached in one region. It is not the carrier's national address space, and it is shared, behind carrier grade NAT, with the ordinary phones in that area. When your worker calls rotate, the modem detaches and re-attaches, and the gateway picks an address from what is free in that pool at that instant. Free is the operative word: if your previous address was not claimed by another device during the seconds you were offline, it is still free, and you may get it straight back.
The consequence is that repeats are a function of the pool, not of your code. A busy pool reassigns released addresses within seconds, so repeats are rare. A quiet pool hands the same address back often, which is fine for a worker holding a logged-in session and annoying for a worker that wanted a new address per task. Write the automation on the assumption that repeats will happen and you will never be surprised by them.
The rotate, read, compare loop
The core of the pattern is three calls. Your worker sends a rotation request, either to the NeonProxies API or by hitting the per-proxy rotation link. It then waits for the modem to finish re-attaching, which takes seconds rather than minutes. Finally it makes one request through the proxy to an address echo endpoint you control or trust and records the public address it sees. Do not assume the rotation succeeded because the API returned; read the address back and let the number decide.
The comparison is where most people go wrong. Comparing against only the immediately previous address misses the common case where the gateway alternates between two or three addresses. Compare against a short memory of everything this worker has held recently, and treat any hit as a repeat. Below is the loop as most of our automation customers implement it.
- Send the rotation call for this worker's proxy and note the time
- Wait for the re-attach, then fetch the public address through the proxy
- Look the address up in this worker's recent-address memory
- If it is new, record it and continue the task
- If it is a repeat, apply the retry rule described in the next section
Per-worker memory and a small retry budget
Give each worker its own memory of addresses seen, keyed by proxy, and expire entries after roughly a day. A day matches the window most targets care about when they attribute activity to an address, and it keeps the memory tiny. Do not share the memory across workers on different lines; the pools are different and a collision across lines is not a repeat in any sense the target will notice.
On a repeat, rotate again, but with a budget. Two or three attempts is the right order of magnitude. Between attempts, back off: wait longer than you did the previous time before re-attaching, because the extra seconds offline are what give another device the chance to take the released address. Rotating instantly in a tight loop just re-attaches before anything has changed. Once the budget is spent, stop retrying on that line, log the event, and hand the task to a different worker. Never let the retry loop run unbounded; a quiet pool will happily hand back the same address a hundred times, and every attempt costs you seconds of downtime on that modem.
Sticky sessions per worker
Not every worker should rotate at all. If a worker owns a logged-in account, a checkout flow, or anything with server-side session state, give it a sticky session: attach once, keep the address for as long as the carrier permits, and only rotate at a task boundary you choose. Carriers generally let an active data session hold an address for days or weeks, though some networks reset on a session timer, so plan for the address to change eventually and handle it gracefully rather than treating it as fatal.
The clean architecture is one line per sticky worker and a separate group of lines for fresh-address work. Mixing both roles on one line means the rotation your scraper triggered just logged your account worker out. Because every NeonProxies proxy is one modem and one SIM assigned to one customer, nobody else is rotating your line, so the only rotations that happen are the ones your code sends.
Measuring yield from your own counters
Once the loop is in place you get a useful side effect: your worker's memory doubles as a yield meter. Count rotations and count first-time addresses per line, and the ratio tells you how fresh that line is right now. Track it over days and you will see the discovery curve every line follows. New addresses arrive quickly at first, then more slowly as the line has seen most of what its gateway routinely hands out, without ever fully stopping. As a rule of thumb, a line rotated many times a day tends to show a few hundred distinct addresses in a week and low thousands over a quarter, though the exact figure depends on carrier, metro and cadence.
Keep long-run depth and short-term freshness as separate numbers. A line can have uncovered plenty of addresses this month and still repeat itself this afternoon. The short-term number is the one your retry logic reacts to; the long-run number is the one that tells you whether to keep the line at all.
When to switch line, carrier or metro
If a worker keeps exhausting its retry budget, the problem is the pool it is on, and no amount of retry tuning changes the pool. The lever that does is carrier and location. Each carrier runs a different block in each of our eight metros, and the three carriers behave differently within one metro. In our racks Verizon lines tend to hand out a fresh address readily, AT&T lines tend to be stickier and revisit addresses more often, and T-Mobile varies a lot from one city to the next. Treat those as tendencies that shift over time, not as fixed properties.
Rather than coding around a shallow pool forever, have your automation flag the line and ask support to switch it to another carrier in the same metro or move it to a different city. Both changes are free and happen on our side. It also pays to spread a fleet of workers across two carriers or two metros from the start, so a single quiet pool never stalls the whole job.
What to do next with NeonProxies
Implement the rotate, read, compare loop with a per-worker memory, a retry budget of two or three and increasing back-off, and separate your sticky workers from your fresh-address workers on different lines. Run it against the real target for a day and watch the first-time address ratio per line. If one line is starving your workers, open the live chat on the site and tell us the metro and the job.
We will tell you which carrier line in that city is currently rotating freshest, and we can switch carrier or move the proxy to another metro at no cost. Repeats from a finite pool are a known quantity; the code above turns them from an outage into a log line.
Frequently asked
The rotation API returned success but the address is the same. Did it fail?
No. The modem detached and re-attached, and the gateway handed back the address that was still free, which was yours. On a lightly loaded pool that is common. Wait a little longer offline before the next attempt, rotate again, and if it persists ask support to lengthen the detach on that line.
How large should the per-worker address memory be?
Small. Keep every address the worker has held in roughly the last day, keyed by proxy, and expire older entries. That covers the window targets typically use to tie activity to an address, and it stays a handful of entries per line. Do not merge memories across lines on different pools.
What retry budget should I use on a repeat?
Two or three rotations, each after a longer wait than the last. If the address is still a repeat after that, the pool is quiet or shallow right now and further retries only add downtime. Mark the line, hand the task to another worker, and let support switch the line if it keeps happening.
Can I hold one address for a whole multi-hour job?
Yes. Use a sticky session: attach once and do not send rotation calls. The carrier will usually keep the address for days or weeks, although some networks reset on a timer, so write the worker to survive an eventual change. Put sticky workers on their own lines so nothing else rotates them.
Does a shared carrier address make my automation harder to attribute?
Not by itself. Many phones share each address behind carrier grade NAT, but platforms attribute by account, device fingerprint and behaviour, not by address alone. The value of the carrier address is trust from the carrier network and consistent geography per identity, so keep each identity on one line and one city.
How do I know which line in my city rotates freshest today?
Ask live chat. It changes by carrier, metro and time, and we see the lines every day. If your workers are starving on one carrier we can switch the proxy to another carrier in the same metro or move it to any of our other US cities for free.