Why your sticky proxy session keeps changing IP

2026-07-21 · Bazyl

A sticky session that will not stay put is almost always one of six things. Four are bugs in how the endpoint is built or reused, and you can fix those outright. Two are the network being what it is.

Work down the list in order — it is roughly ordered by how often each turns out to be the culprit.

1. The lifetime expired

The boring answer, and the most common one. _lifetime-30 means thirty minutes, after which the pool takes the address back and your next request starts somewhere new. Nothing is broken. You asked for thirty minutes and got them.

The fix is to size the window to the work: set a lifetime slightly longer than the task needs, or drop the timer entirely with _lifetime-hard. In the dashboard that is the Max button next to the duration slider — the walkthrough is here.

2. The flag is in the wrong place

Flags ride the password, separated by underscores, in a fixed order: country, then city, then session, then lifetime. Put them on the username, reorder them, or separate them with something else, and the request stops asking for what you think it is asking for.

The tell is that it looks exactly like plain rotation, because that is the default when nothing valid asks otherwise. A correct residential string looks like this:

residential.basilproxies.com:1000:USER:PASS_country-US_session-k4mz61pq_lifetime-hard

Generate one in the dashboard and compare yours against it character by character. This takes a minute and settles the question.

3. Your code makes a new session id every request

The classic. A helper that builds a proxy string calls its random-id generator inline, so every call produces a new id, so every request is a new session:

# Wrong — a new id, and therefore a new IP, on every call
def endpoint():
    sid = "".join(random.choices(string.ascii_lowercase + string.digits, k=8))
    return f"http://{USER}:{PASS}_session-{sid}_lifetime-hard@{HOST}:1000"

Generate the id once, at the start of the unit of work that needs one address, and pass it down:

# Right — one id per worker, held for as long as that worker needs its address
def endpoint(sid):
    return f"http://{USER}:{PASS}_session-{sid}_lifetime-hard@{HOST}:1000"

sid = "".join(random.choices(string.ascii_lowercase + string.digits, k=8))
proxy = endpoint(sid)

Same bug, different shape: a browser automation harness that re-reads a proxy list per page, or a pool object that round-robins your generated strings. If something upstream is choosing a line for you, the session flag never had a chance.

4. The IP went offline

This one is not a bug. A residential IP is a real household connection, and it disappears when someone reboots a router, when a phone leaves Wi-Fi, when a laptop sleeps. _lifetime-hard removes the timer; it does not keep somebody's home internet online.

There is no configuration that prevents this. What you do instead is notice it early and handle it deliberately:

def exit_ip(proxy):
    return requests.get(
        "https://ipinfo.io/ip", proxies={"http": proxy, "https": proxy}, timeout=10
    ).text.strip()

start = exit_ip(proxy)
# ... do the work ...
if exit_ip(proxy) != start:
    # The address changed. Restart this flow on a new session id rather than
    # continuing — anything session-bound on the target side is already gone.
    ...

Check before the step you cannot afford to lose, not after. And when the address does change, start the flow over on a fresh id — retrying the old id harder just asks the pool for an IP that is no longer there.

5. You are reading a different address than you think

Occasionally the session is fine and the measurement is wrong. Echo services behind a CDN can report an edge address rather than yours. A browser leaking a direct request outside the proxy reports the machine's own address. Two different checker services sometimes disagree because they are measuring different hops.

Pin one plain endpoint — ipinfo.io/ip is fine — and compare like with like before concluding anything.

6. The target is telling you something else

A site that suddenly behaves as if you are a new visitor has not necessarily moved you. Cleared cookies, an expired login, a fresh browser profile, or a fingerprint mismatch all look like "the proxy changed" from the outside.

Confirm the exit IP directly before blaming the session. If the address held and the site still treats you as new, the problem is state on your side, not routing.

When to stop fighting it

If your work genuinely requires an address that survives for weeks, a shared residential pool is the wrong tool and no flag will change that. You are borrowing somebody's home connection, and it was never yours to keep.

ISP proxies are the other answer: an address rented to you for the whole billing period, the same one after every renewal, on our own ASN. No session flag, no lifetime, nothing to hold — it is simply yours until you stop paying for it.

Pick by duration. Minutes to hours, use a session. Weeks, rent the IP.

Common questions

Why does my sticky proxy session keep changing IP?
In order of likelihood — the session lifetime expired, the session flag is malformed or on the wrong part of the credentials, your code generates a fresh session id per request, or the residential IP behind the session went offline. The first three are configuration bugs you can fix outright. The fourth is normal behaviour on a residential network and has to be handled in code.
Does a non-expiring session ever change IP?
Yes. Non-expiring removes the timer, not the possibility. Residential IPs are real home connections, and when the device behind one disconnects the session ends with it. The correct response is a new session id and a restart of whatever flow you were in.
How do I stop my proxy IP from changing at all?
You cannot fully, on a shared residential pool — the address is borrowed from a household you do not control. If an unchanging address is a hard requirement, use a dedicated ISP proxy instead. It is rented to you for the billing period and stays the same after renewal.
How long should a sticky session last?
Set it slightly longer than the task, not as long as possible. If a checkout takes eight minutes, a 15-minute session is right. Long sessions concentrate all of your traffic and all of your reputation on one address, which is a cost, not a bonus.
My session id is correct but every request still shows a different IP. What now?
Check that the flag is on the password rather than the username, that the order is country then city then session then lifetime, and that your HTTP client is not being handed a newly built proxy string per request. Compare your string character by character against one generated in the dashboard.