Comparisons

Sticky vs Rotating Proxy Sessions: When to Use Each

Sticky and rotating are two answers to one question: should the next request go out from the same IP as the last one, or a fresh one? Get the answer wrong and you either look like a bot that teleports between cities mid-login, or you waste a perfectly good session by never reusing it. This is a practical guide to picking the right one — and a look at how the o2co endpoint lets you make the choice per connection.

What each mode actually means

A sticky session holds one egress IP across a sequence of requests. Everything you send — the login POST, the CSRF token fetch, the add-to-cart, page 2 of the results — leaves from the same address. To the target, it reads as one person on one connection doing one continuous thing.

A rotating session changes the egress IP frequently, so consecutive requests can come from different addresses. Each request looks like an independent visitor. For background on the mechanics, see What Is a Rotating Proxy?

Why flipping IP mid-session trips anti-bot

Web apps build a story about who you are from the request stream. A normal user logs in, and every subsequent request carries that session's cookies from the same IP. That consistency is load-bearing — a lot of anti-fraud logic assumes it.

Now picture what an IP change mid-flow looks like from the server's side:

  • You authenticate from an IP in Frankfurt.
  • Two seconds later the cart request arrives from São Paulo with the same session cookie.
  • The next page-load comes from a third address entirely.

No human travels nearly 10,000 km between clicks. Many sites check the session against the IP (or its ASN / rough geo) and will silently invalidate the session, throw a fresh CAPTCHA, or hard-block the moment the IP jumps. Some go further and bind session or CSRF tokens to the client IP, so a request replayed from another address simply 403s with no obvious reason. IP consistency is one of the cheapest bot signals a site has, which is exactly why it gets used. More on the broader detection surface in How Websites Detect Proxies.

Rule of intuition: if losing the IP would break the workflow for a real logged-in user, you need stickiness. If each request stands on its own, rotation is free protection.

Sticky or rotating: how our endpoint handles it

o2co is a single proxy endpoint — the host and port on your dashboard, speaking HTTP or SOCKS5 on the same port, with username/password auth — and you pick sticky or rotating per connection, in the username. Sticky is the default, because rotation done naïvely is a trap: a single modern page-load pulls in dozens of resources (HTML, CSS, JS, images, fonts, XHR/fetch calls) over many proxy connections, usually one or more per origin. If each connection went out from a different IP, the target would watch its own page assemble itself from several countries at once — an obvious bot tell.

So the plain username, USERNAME:PASSWORD@HOST:PORT, uses burst stickiness: a machine that keeps sending keeps its exit. The pin is keyed on your account and your source IP and is refreshed by every new connection; only after about a minute with no new connections can the next one get a fresh exit. A page-load, a login-then-browse flow, a cart or a checkout stays on one IP; the next burst after a pause may get a new one. That is the right mode for browsers, logins and multi-step flows, and it is what our Chrome extension always uses. If you need one exit held across longer pauses, sticky mode (one exit per source IP for a 10-minute window) is an account-level setting.

For crawlers, add -rotate: USERNAME-rotate:PASSWORD@HOST:PORT. Every new connection may then leave from a different exit — the gateway picks from your account's healthy exits without repeating the previous one, so two consecutive connections never share an exit when at least two are available. Rotating connections leave the sticky pin of your plain-username connections alone, and they cost nothing extra: same per-GB rate. One IP for a whole crawl is how a crawler gets captcha'd; -rotate spreads it.

One honest caveat: rotation is per connection, not per HTTP request. A keep-alive or pooled connection keeps its exit for as long as it stays open, and most HTTP clients (requests, Scrapy, Playwright) reuse connections by default. For a new IP on every request, open a new connection per request — send Connection: close, or turn off the client's connection pool.

The other knob you control per connection is country. Append -country-xx (two lowercase letters, ISO 3166-1 alpha-2, from the countries your plan allows) to your username, and that connection egresses through the chosen country. It combines with -rotate in either order. Suffixes are lowercase and exact (-ROTATE or -country-DE fails authentication), and there is no named-session parameter: sticky or rotate, plus country, is the whole menu.

# Default (sticky): one exit while traffic flows, a fresh one after ~1 min idle
curl --proxy http://USERNAME:PASSWORD@HOST:PORT https://example.com

# Rotate: each curl run is a new connection, so each may get a different exit
curl --proxy http://USERNAME-rotate:PASSWORD@HOST:PORT https://api.ipify.org
curl --proxy http://USERNAME-rotate:PASSWORD@HOST:PORT https://api.ipify.org

# Pin egress to Germany for this connection:
curl --proxy http://USERNAME-country-de:PASSWORD@HOST:PORT https://ifconfig.co/country

# Rotate within Germany (USERNAME-rotate-country-de works too):
curl --proxy http://USERNAME-country-de-rotate:PASSWORD@HOST:PORT https://ifconfig.co/country

# Prefer SOCKS5? Same port, same credentials:
curl --proxy socks5h://USERNAME:PASSWORD@HOST:PORT https://example.com

Residential and datacenter upstreams sit behind the same endpoint and credentials; your plan sets which pools you draw from, so there are no separate tools or accounts to juggle.

Rule of thumb

If your task…You want…Why
Logs in and stays logged inStickyMany apps check the session against the IP
Adds to cart, checks outStickyMulti-step state must hold on one IP
Submits a form with a CSRF tokenStickySome apps bind the token to the client IP
Paginates through one result setStickyPages 2–N belong to the same logical visit
Fetches many independent public pagesRotating (-rotate)Each read stands alone; spread the footprint
Checks a price or stock value once eachRotating (-rotate)No shared state to preserve
Renders a JS-heavy page (assets + XHR)Burst-sticky (the default)One render must come from one IP

Tying it to real workloads

Account-based automation — anything behind a login, a multi-page form, or a checkout — is sticky territory. The whole flow should ride one IP from the first request to the last. On our endpoint that happens by default as long as the flow doesn't pause past the idle window; for flows with long gaps, use sticky mode.

Wide, shallow data collection — crawling a category tree, sampling prices across thousands of independent product URLs, gathering public listings — benefits from rotation. Each request is self-contained, so spreading them across many IPs lowers the per-IP request rate and keeps any single address from drawing attention. This is the standard shape for web scraping, where the failure mode is volume from one IP, not lost session state. On our endpoint, that is the -rotate suffix.

Most real projects mix both. A scraper that has to authenticate first and then page through results wants a sticky IP for the authenticated portion and can rotate freely for any unauthenticated, independent fetches around it — here, the plain username for the first and -rotate for the second, without one disturbing the other. The deciding question never changes: does this next request depend on the state the last one created? If yes, hold the IP. If no, let it rotate.

The short version

  • Sticky when state crosses requests — login, cart, CSRF, pagination within one visit.
  • Rotating when requests are independent — bulk reads of public pages, one-shot lookups.
  • Sticky is the default here: one exit while traffic flows, a fresh one after about a minute idle.
  • Add -rotate to the username and every new connection may take a different exit — per connection, not per request, so don't reuse connections if you want a new IP each time.
  • Pick the country per connection with the -country-xx username suffix (it combines with -rotate); the longer sticky mode is an account setting.

Want to see it on your own workload? Get 1 GB free or see pricing. Setting up a client first? Start with the setup guide.