Sticky sessions and cookie handling, now up to 30 minutes
Residential sticky sessions can now last up to 30 minutes. How sessions work at the gateway, how to pair them with cookie jars so each identity stays consistent, and what to do when a peer disappears mid-session.
On this page
With release 4.0, residential sticky sessions can last up to 30 minutes, up from 10. Longer sessions make multi-step flows far more reliable — but only if the rest of your client treats a session as one consistent identity. This guide covers how sessions work on our gateway, how to manage cookies alongside them, and how to handle the edge cases.
How a sticky session works
On the residential gateway, everything is configured in the proxy username:
LOGIN-country-CC[-city-CITY]-session-ID-ttl-MINUTES
session-IDis an 8-character alphanumeric string you choose. The gateway keeps a mapping from that ID to one residential peer.ttl-MINUTESis how long the mapping should last, from 1 to 30 minutes.
The first request with a new session ID picks a peer matching your country and city targeting. Every following request with the same ID — on any connection, HTTP or SOCKS5 — exits from that same peer until the TTL expires. After that, the same ID picks a new peer.
The TTL starts with the first request, not the last: a 15-minute session ends 15 minutes after it began, however active it is. Plan your flows so they complete within the TTL, with a margin.
Existing usernames with a TTL of 10 minutes or less keep working exactly as before.
A session is an identity, not just an IP
The most common mistake we see is using sticky sessions for the IP alone while sharing one cookie jar across every session. From the target's point of view, that is one browser whose address jumps between households — a far stronger bot signal than an IP change on its own.
Treat each session ID as a complete identity:
| Element | Per session |
|---|---|
| Exit IP | Fixed by the session ID |
| Cookie jar | One jar, created with the session, discarded with it |
| User agent and client hints | Chosen once, kept constant |
| Accept-Language | Consistent with the exit country |
| Local storage (browsers) | One browser context per session |
When the session ends, end all of it: new ID, new cookie jar, new context.
Example: Python with requests
import secrets
import requests
GATEWAY = "resi.gw.proxuno.com:7000"
LOGIN, PASSWORD = "LOGIN", "PASSWORD"
def new_identity(country="fr", city=None, ttl=20):
sid = secrets.token_hex(4) # 8 hex characters
user = f"{LOGIN}-country-{country}"
if city:
user += f"-city-{city}"
user += f"-session-{sid}-ttl-{ttl}"
proxy = f"http://{user}:{PASSWORD}@{GATEWAY}"
s = requests.Session() # fresh cookie jar
s.proxies = {"http": proxy, "https": proxy}
s.headers.update({
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 "
"(KHTML, like Gecko) Chrome/128.0.0.0 Safari/537.36",
"Accept-Language": "fr-FR,fr;q=0.9,en;q=0.6",
})
return s
s = new_identity(country="fr", city="lyon", ttl=20)
s.get("https://example.com/") # consent / session cookies set here
s.get("https://example.com/search?q=velo&page=2") # same IP, same cookies
Example: Playwright browser contexts
In a browser, a context is the natural unit of identity: its own cookies, storage and cache. Give each context its own session:
const { chromium } = require('playwright');
const browser = await chromium.launch();
const sid = Math.random().toString(36).slice(2, 10);
const context = await browser.newContext({
proxy: {
server: 'http://resi.gw.proxuno.com:7000',
username: `LOGIN-country-de-city-berlin-session-${sid}-ttl-30`,
password: 'PASSWORD',
},
locale: 'de-DE',
timezoneId: 'Europe/Berlin',
});
const page = await context.newPage();
await page.goto('https://example.com/');
// … the whole flow …
await context.close(); // identity discarded with the session
Setting locale and timezoneId to match the exit country removes two easy inconsistencies.
When the peer disappears
Residential peers are real household devices. A phone can leave Wi-Fi, a laptop can go to sleep. If the peer behind your session goes offline, the gateway assigns a new peer with the same targeting on the next request. Your session ID keeps working, but the IP changes.
How to handle it depends on the flow:
- Stateless pages (search results, product pages): just retry. The new IP is as good as the old one.
- Flows with server-side state (a basket, a multi-page form, a login): the target may now see the same cookies from a new address. For most sites this is unremarkable — people switch networks — but for sensitive flows, restart the identity cleanly: new session ID, new cookie jar.
You can detect a change by calling an IP echo service such as https://api.ipify.org through the same session at the start of each sensitive step and comparing the result with the address you saw before.
Choosing a TTL
Longer is not automatically better. Each minute a session lasts is a minute your traffic is concentrated on one household's connection.
| Flow | Suggested TTL |
|---|---|
| Pagination through search results | 5–10 min |
| Product page plus availability and price checks | 2–5 min |
| Multi-step form or checkout test | 10–20 min |
| Browsing session in a headless browser | 15–30 min |
Start short, measure how often flows fail mid-way, and lengthen only where you need to.
Sessions and billing
Sticky sessions cost nothing extra. You pay for the traffic transferred, as with per-request rotation. The number of concurrent sessions is not limited by us; it is limited by politeness. We recommend no more than one or two concurrent connections per session, which is how a real household browser behaves.
The sticky sessions documentation has the full username reference, error codes and examples for SOCKS5.