Skip to content
Session Management

Sticky Sessions

Maintain the same proxy IP address across multiple requests. Essential for login flows, checkout processes, form submissions, and any multi-step workflow that requires IP consistency.

How Sticky Sessions Work

When you add a session ID to your residential proxy credentials (_session-ID in the password on Light and Basic, -session-ID in the username on Advanced), ZentisLabs pins that session to a specific IP address. All subsequent requests with the same session ID will use the same IP for the duration of the TTL (time-to-live). Use letters and digits for session IDs. Sticky lines generated in the dashboard or API may use a single gateway IP instead of the hostname so the exit IP stays the same; use them as-is.

1

First Request

IP assigned and pinned to your session ID

2

Subsequent Requests

Same session ID → same IP address

3

TTL Expires

After TTL, new IP assigned on next request

Proxy TypeSession LengthHow to Set It
Residential - LightNo length parameter_session-ID in the password
Residential - Basic_lifetime-30m (minutes)In the password, after _session-ID
Residential - Advanced-sessionduration-30 (minutes)In the username, after -session-ID
MobileUp to 4 hoursChosen in the dashboard when you generate a Sticky line
ISPPermanentStatic IP, never rotates
Datacenter-Choose Sticky when you generate

Basic Sticky Session

bash
# Add a session ID to the password to maintain the same IP
SESSION="mysession001"
# Request 1 - IP is assigned
curl -x "http://USERNAME:PASSWORD_country-us_session-$SESSION@basic.resi.zentislabs.com:12321" \
"https://httpbin.org/ip"
# Request 2 - same IP used
curl -x "http://USERNAME:PASSWORD_country-us_session-$SESSION@basic.resi.zentislabs.com:12321" \
"https://httpbin.org/ip"
# Both requests show the same origin IP
python
import requests
SESSION_ID = "checkoutflow42"
proxy = f"http://USERNAME:PASSWORD_country-us_session-{SESSION_ID}@basic.resi.zentislabs.com:12321"
proxies = {"http": proxy, "https": proxy}
# Use requests.Session for connection reuse
session = requests.Session()
session.proxies = proxies
# All requests use the same proxy IP
r1 = session.get("https://example.com/login")
r2 = session.post("https://example.com/add-to-cart", json={"item": "SKU-123"})
r3 = session.post("https://example.com/checkout")
# Verify same IP
ip1 = session.get("https://httpbin.org/ip").json()["origin"]
ip2 = session.get("https://httpbin.org/ip").json()["origin"]
assert ip1 == ip2, "IP should be the same"
print(f"Both requests used IP: {ip1}")
typescript
import axios from "axios";
import { HttpsProxyAgent } from "https-proxy-agent";
const sessionId = "usersession42";
const agent = new HttpsProxyAgent(
`http://USERNAME:PASSWORD_country-us_session-${sessionId}@basic.resi.zentislabs.com:12321`
);
// All requests use the same IP
const [r1, r2, r3] = await Promise.all([
axios.get("https://httpbin.org/ip", { httpsAgent: agent }),
axios.get("https://httpbin.org/ip", { httpsAgent: agent }),
axios.get("https://httpbin.org/ip", { httpsAgent: agent }),
]);
console.log(r1.data.origin, r2.data.origin, r3.data.origin);
// All three show the same IP

Advanced Patterns

Session per Account

Assign a unique session per account/user to maintain consistent IP identity.

python
import requests
import hashlib
def get_proxy_for_account(account_id: str) -> dict:
"""Create a unique sticky session per account."""
session_id = hashlib.md5(account_id.encode()).hexdigest()[:12]
proxy = f"http://USERNAME:PASSWORD_country-us_session-{session_id}@basic.resi.zentislabs.com:12321"
return {"http": proxy, "https": proxy}
# Each account always gets the same IP
accounts = ["user_alice", "user_bob", "user_charlie"]
for account in accounts:
proxies = get_proxy_for_account(account)
r = requests.get("https://httpbin.org/ip", proxies=proxies)
print(f"{account}: {r.json()['origin']}")

Session with Custom TTL

bash
# Basic: set the session length with _lifetime-<N>m after the session ID
# _lifetime-5m = 5-minute TTL
curl -x "http://USERNAME:PASSWORD_country-us_session-abc123_lifetime-5m@basic.resi.zentislabs.com:12321" \
"https://httpbin.org/ip"
# _lifetime-30m = 30-minute TTL
curl -x "http://USERNAME:PASSWORD_country-us_session-abc123_lifetime-30m@basic.resi.zentislabs.com:12321" \
"https://httpbin.org/ip"
# Advanced: -sessionduration-<minutes> in the username (Light has no length parameter)
curl -x "http://USERNAME-country-us-session-abc123-sessionduration-30:PASSWORD@advanced.resi.zentislabs.com:61236" \
"https://httpbin.org/ip"

Session Rotation Strategy

python
import requests
import time
def scrape_with_session_rotation(urls: list[str], batch_size: int = 50):
"""Rotate session ID every batch_size requests to get fresh IPs."""
results = []
for i, url in enumerate(urls):
session_id = f"batch{i // batch_size}"
proxy = f"http://USERNAME:PASSWORD_country-us_session-{session_id}@basic.resi.zentislabs.com:12321"
proxies = {"http": proxy, "https": proxy}
try:
r = requests.get(url, proxies=proxies, timeout=30)
results.append(r.json())
except requests.RequestException as e:
print(f"Failed {url}: {e}")
return results
urls = [f"https://example.com/page/{i}" for i in range(200)]
data = scrape_with_session_rotation(urls)

Best Practices

Use descriptive session IDs

Include context in your session ID (e.g., 'checkoutUser42', letters and digits only) for easier debugging and monitoring.

Don't reuse expired sessions

After TTL expires, use a new session ID. Reusing an expired ID may assign a different IP.

Match session to workflow

Use one session per workflow (login→checkout). Don't share sessions across unrelated tasks.

Monitor session health

Track success rates per session. If a session's IP gets blocked, create a new session immediately.

Set appropriate TTL

Use the shortest TTL that covers your workflow. Longer TTLs hold IPs from the pool longer.

Handle session expiry gracefully

Implement retry logic that creates a new session if the current one returns errors.

Troubleshooting

Session returns different IPs

The session likely expired. Check the TTL and create a new session. Also verify the session ID is identical across requests, and use the sticky line generated in the dashboard or API as-is: it may point at a single gateway IP, while a hand-built line with the hostname can reach a different gateway node.

Session IP is blocked

Create a new session with a different ID. The new session will be assigned a fresh IP from the pool.

Session drops mid-workflow

Use a longer session length (Basic: _lifetime-<N>m, Advanced: -sessionduration-<minutes>) or implement retry logic that detects IP changes and re-creates the session.