Skip to content

Rotating and sticky sessions

Leave the session part out and the gateway assigns exit IPs (rotating). Add -session-{SID}-ttl-{MIN} and requests with the same session ID keep the same exit IP for that many minutes while it stays available (sticky).

Updated
Reading time
4 min
Checked against
3 sources

You choose the session mode per request, in the username. A sticky session proxy username pins the exit IP for a lifetime you set, while that IP stays available; a rotating one doesn't pin it. The gateway, the port and the password stay the same in both modes.

ModeUsernameExit IP
RotatingUSERNAME-cc-USAssigned by the gateway, not pinned
StickyUSERNAME-cc-US-session-a1b2c3d4-ttl-30The same for 30 minutes while it stays available

Rotating sessions

A username without session parameters, such as USERNAME-cc-US, is a rotating session: the gateway assigns exit IPs, and the exit IP isn't pinned to your requests.

Requests sent through one HTTPS tunnel share that tunnel's exit IP. If consecutive requests must share an exit IP, use a sticky session instead of relying on how your client reuses connections.

Rotating sessions suit independent requests, where it doesn't matter whether two requests leave from the same IP: separate page fetches, scheduled checks of public pages, or one-off lookups.

Sticky session proxy syntax

Add -session- with a session ID and -ttl- with a lifetime in minutes after the country code:

Sticky username
USERNAME-cc-{CC}-session-{SID}-ttl-{MIN}
USERNAME-cc-US-session-a1b2c3d4-ttl-30

Requests that use the same session ID keep the same exit IP for the TTL, while that IP stays available. Always send -session- and -ttl- together.

Session IDs

  • Use letters and digits only, no hyphens. The dashboard generates 8 lowercase characters, such as a1b2c3d4.
  • Reuse an ID to stay in the same session. Use a new ID to start a new session.
  • Give each task, worker or agent run its own ID. Workers that share an ID share one session, and with it one exit IP.
  • Generate IDs in code: in Python, secrets.token_hex(4) returns 8 characters from 0-9 and a-f; in Node.js, randomBytes(4).toString("hex") from node:crypto does the same.

Session lifetime (TTL)

-ttl- sets how long the session keeps its exit IP, in minutes. The dashboard offers these presets:

Sticky session presets offered in the dashboard
Dashboard presetUsername suffix
15 minutes-session-a1b2c3d4-ttl-15
30 minutes-session-a1b2c3d4-ttl-30
12 hours-session-a1b2c3d4-ttl-720
7 days-session-a1b2c3d4-ttl-10080

The dashboard offers sticky lifetimes from 15 minutes up to 7 days. Include -ttl- every time you use -session-, and pick the shortest lifetime that covers the task. When the lifetime ends, don't count on the same exit IP: start the next task with a new session ID.

When the exit IP changes early

A sticky session keeps its exit IP only while that IP stays available. Residential and mobile exit IPs can become unavailable before the TTL ends, and then the next request in the session may leave from a different IP.

If your task depends on one IP, detect the change instead of assuming it can't happen:

  1. Record the exit IP at the start of the task, for example from https://api.ipify.org?format=json through the same session.
  2. Check it again before steps that depend on it, or watch for signs that the website no longer recognizes your session, such as a multi-page form starting over.
  3. If the IP changed, restart the step with a new session ID rather than continuing halfway on a different IP.

Choosing rotating or sticky

AttributeModeLifetime
Independent page fetchesRotatingNo session parameters
A multi-step flow on one websiteSticky15 or 30 minutes (-ttl-15, -ttl-30)
An AI agent taskSticky, one session ID per runA preset that covers the whole run
A long QA or testing sessionSticky12 hours (-ttl-720)

Browser automation often runs multi-step flows across several pages, which is what sticky sessions are for. See browser automation and the Playwright guide for complete setups.

Sessions across plans

The session syntax is the same on Solve, Scale, the Opus plan and Mobile, so code that builds sticky usernames works on every residential and mobile plan. The Opus Extended and HighSpeed pools on eligible Opus accounts use usernames generated in the dashboard and have longer default sticky sessions. Static ISP and datacenter IPs take no session parameters: each IP stays assigned to you for as long as the subscription renews.

Examples

Sticky sessions with curl in the US and Germany, and a Python script that generates its own session ID and prints the exit IP of two requests in that session:

cURL (US)
curl --max-time 30 -x "http://USERNAME-cc-US-session-a1b2c3d4-ttl-30:PASSWORD@scale-us.netdash.io:2000" \
  "https://api.ipify.org?format=json"
cURL (Germany)
curl --max-time 30 -x "http://USERNAME-cc-DE-session-a1b2c3d4-ttl-30:PASSWORD@scale-eu.netdash.io:2000" \
  "https://api.ipify.org?format=json"
Python
import os
import secrets
from typing import Optional

import requests

GATEWAY = "scale-eu.netdash.io:2000"  # Scale plan, Europe gateway


def proxy_url(country: str, session_id: Optional[str] = None, ttl: int = 30) -> str:
    username = f"{os.environ['NETDASH_USERNAME']}-cc-{country}"
    if session_id:
        username += f"-session-{session_id}-ttl-{ttl}"
    return f"http://{username}:{os.environ['NETDASH_PASSWORD']}@{GATEWAY}"


session_id = secrets.token_hex(4)  # 8 characters, letters and digits only
proxy = proxy_url("DE", session_id)
proxies = {"http": proxy, "https": proxy}  # set both, or HTTPS requests skip the proxy

for _ in range(2):
    response = requests.get("https://api.ipify.org?format=json", proxies=proxies, timeout=30)
    response.raise_for_status()
    print(session_id, response.json()["ip"])
Checked against a local test proxy

The Python script reads NETDASH_USERNAME and NETDASH_PASSWORD from the environment. Load them from a .env file or your secret manager, and never commit them to source control. The proxy format reference has sticky session examples for Node.js and Go.

Choosing the exit country works the same way in both modes: see country targeting.

Stuck? See troubleshooting or email support.

Sources

Third-party behaviour described on this page was checked against these documents.

  1. 01Python documentation: secrets.token_hexAccessed 2026-10-09
  2. 02Node.js documentation: crypto.randomBytesAccessed 2026-10-09
  3. 03Requests documentation: Advanced Usage, ProxiesAccessed 2026-10-09

Spotted something out of date? Tell us.

Privacy choices

We use cookies and similar technologies that this site needs to work and to remember your choice. We also use Google Analytics to understand which pages and features people use: in the EEA, the UK and Switzerland only with your consent. Live chat loads only if you open it. You can change your choice at any time under “Privacy choices” in the footer. Privacy Policy

Privacy choices

Choose what netdash.io may use. You can change this at any time under “Privacy choices” in the footer.

Necessary (always on)

Keeps the site working and secure, and remembers your privacy choices (nd_consent, 12 months).

In the EEA, the UK and Switzerland it stays off until you switch it on; elsewhere it is on unless you switch it off here. Google Analytics 4 measures page views, clicks on links and buttons, use of the price calculator, connection builder and code examples, scroll depth, file downloads, and page-performance metrics. It sets the cookies _ga and _ga_96MPNM6GHH, which last up to 12 months. Google processes this data, which may involve transfer to the United States. We do not send your name, email address or account details to Google Analytics. With this switched on we also remember a referral code or campaign you arrived with (nd_attr, 30 days), so a partner can be credited if you sign up.

Support chat (loads only when you open it)

Our live chat is provided by LiveChat. It loads only when you open the chat window. LiveChat then sets its own cookies and processes the messages you send and technical data about your browser.