Rotating or sticky: a decision you can make before your next run

Rotating or sticky is a fit test, not a taste. Twenty requests show what a line does, and one timed run shows whether your job fits in the window.

  • Published November 6, 2026
  • 9 min read
In this article
  1. The minutes field turns the hold on, not the session ID
  2. Count the exits: twenty requests settle what the line does
  3. What rotation breaks: anything with state
  4. What sticky breaks: one address carrying the whole run
  5. Whether the run fits inside 120 minutes decides the pool
  6. One instrumented run of your own flow decides it
One line entering from the left and splitting: the upper branch scatters into dashed segments across many small nodes, the lower branch runs unbroken through four nodes.

Step three of a four-step account form keeps bouncing you back to the login page. Steps one and two came back 200, the cookie jar looks fine, the CSRF token was issued thirty seconds ago. You add the exit IP to the log line, run it again, and there it is: two addresses in a flow that was supposed to have one.

The proxy didn't break anything. It did what the username told it to, which was rotate, and the site noticed a logged-in session hop to a different house between filling the form and submitting it.

This is why I think of rotating versus sticky as a fit test rather than a preference you form once and keep. You can't hear a wrong choice. When a session ends, the next request on that credential just leaves from a new IP; there's no error code, no retry hint, no callback telling you it happened. What you get instead is a target behaving strangely.

Two questions decide it, and both can be answered by measuring rather than guessing. Does your job need one identity across a stretch of requests? And if so, how long is that stretch?

The minutes field turns the hold on, not the session ID

Here's the line people ship by mistake:

USERNAME~us~54261cfe

It has a session ID, so it reads as sticky. It rotates.

The relay parses the username by position, user~cc~sessid~minutes, and it only goes down the sticky path when that last field is a whole number between 1 and 1440. Rotating lines are allowed to carry a session ID as well, and on its own the ID does nothing you'd notice. Add the minutes:

USERNAME~us~54261cfe~30

Now it's 30 minutes on one exit.

Anything outside 1 to 1440 gets ignored by the same parser, quietly. Put 0 or 2000 there and you've built a rotating line that looks like a sticky one, and nothing in the response will say so. I'd check that number once by eye before any long job.

API batches behave a little differently. If you generate lines through the API and leave sessionDuration out, it defaults to 60. A username you type together yourself gets no such default, because the relay never sees a minutes field to apply it to.

Count the exits: twenty requests settle what the line does

Don't test this against your target first. Point the credential at an IP echo service and count how many addresses come back.

# Change these three. The port is 7777 for HTTP.
PROXY_HOST="your-proxy-host"          # from your dashboard
PROXY_USER="USERNAME~us~54261cfe"     # your username, country, any session ID
PROXY_PASS="PASSWORD"

for i in $(seq 1 20); do
  curl -s -x "http://${PROXY_USER}:${PROXY_PASS}@${PROXY_HOST}:7777" https://icanhazip.com
done | sort | uniq -c | sort -rn

As written, with no minutes, you should get more than one address. How many is up to the pool, so a repeat isn't a fault; a single address with a 20 beside it is. That's rotation.

Tack ~30 onto PROXY_USER and run it a second time. You want a single line with 20 next to it, meaning every request left through the same exit.

Got more than one address on the second run as well? Then the minutes never reached the relay. Print the exact username your HTTP client sends, because it's sometimes not the one in your config, and confirm the last field is a whole number in range.

The whole thing takes seconds, and lines are free to generate (billing is on gigabytes moved, and a run can produce up to 250,000 lines), so I keep a rotating one and a sticky one next to each other while I'm working.

What rotation breaks: anything with state

The rule in our FAQ is the right one, and short: rotate when each request stands alone, hold a session when a run of requests has to come from one IP, like a login or a multi-step form.

Whether requests "feel related" doesn't matter much. What matters is whether the target pins something to your address. A session cookie checked against the IP that first received it would count. So would a form token handed to one client, or a cart. Once a later request leans on an earlier one having come from the same place, rotation will break your flow, and you'll see the break land on whichever step first follows an IP change.

You can use that. Log the exit IP beside every request in the real flow, run it once on a rotating line, and note the first failing step. Failure right after an address change means the target wants sticky. Failure at the same step with one address all the way through means you've got a different bug, and flipping modes won't touch it.

The other kind of job is a list of independent fetches: product pages, say, each one requested cold, no cookies carried over. Rotation has nothing to break there. Oxylabs treats that as the default for rotating residential traffic, describing proxies that "change the IP automatically with every request" (product page, read 2026-11-06).

What sticky breaks: one address carrying the whole run

The reverse mistake takes longer to show up. Hold a single exit across a long batch of independent requests and every one of them arrives from the same address, so whatever opinion the target forms about that address, it applies to the entire batch.

Again, no error. You'll see a refusal rate creeping up on one IP while nothing else in your setup moved. If you chart refusals across the life of each session, the tell is a curve that climbs with time on one exit and falls back when a new session starts. That's a hold running longer than the job needed.

I won't claim rotation prevents that, and I won't give you a percentage by which sticky improves success, because I haven't found anyone who tested the two modes against each other on one provider and one target. How the switch works is documented. What it does to your target, you measure.

The published numbers are useful mostly as a sense of the noise floor. Proxyway's 2026 market research (dated 23 October 2026, which I read on 2026-11-06) measured a median residential success rate of 74.43% against Amazon, Google and Instagram, and the top network reached 81.23% (report). So even the best result in that test lost about one hard-target request in five. A 20% failure rate on your job, on its own, doesn't tell you that you chose the wrong mode; the gap between the two modes on your own job does.

Price doesn't separate them. Within a pool, rotating and sticky lines come out of the same supply at the same per-gigabyte rate, and you pick per line rather than per plan. We meter bytes in both directions through the proxy, so a refused request is billed like a successful one; a mismatched mode costs you in usable pages per gigabyte, not on the invoice line.

Whether the run fits inside 120 minutes decides the pool

Once sticky is settled, time your longest stateful run, from the request that creates the state to the last one that relies on it.

That figure chooses the pool for you. Essential residential holds a session for 120 minutes at most. Premium and Mobile take anything from 1 minute up to 24 hours, the whole 1 to 1440 range. Compare the two on the pricing page today and Premium's window works out to 12 times Essential's ceiling for twice the per-gigabyte rate, so the cap marks the line between tiers rather than adding a fee per session. Nothing you configure on Essential lifts it.

It's applied on our side, and it doesn't reject anything. Ask for a sessionDuration of 240 on Essential and you still get your batch, at 120 minutes. You're told, too, if you look: POST /proxies comes back with session_duration 120, and GET /pools lists session_minutes.max as 120 for Essential. I'd read that field back rather than trust the value I sent.

Older lines have a wrinkle. The cap arrived in API v1.3, in November 2026, and GET /generations still records whatever length was requested on batches made before that, so an old Essential batch may show a number above 120 there. The docs state the rule plainly, and it's the one to plan on: on Essential a session holds at most 120 minutes, whatever value is sent.

We haven't published a reason for Essential stopping at 120, and I'm not going to guess at one here. What you can plan around is the behaviour: 1 to 120 minutes, clamped, reported back.

For the hold you really get, Proxyway's method is easy to borrow. Its session test opened a sticky session and fired a request every 20 seconds until either 30 minutes had passed or the IP changed, across 330 sessions per provider. Run it for 125 minutes instead and you go five minutes past Essential's ceiling.

# Same three variables as above, with minutes set past what you need.
PROXY_USER="USERNAME~us~54261cfe~240"   # change: your username; 240 minutes requested
start=$(date +%s); last=""
while [ $(( $(date +%s) - start )) -lt 7500 ]; do      # 125 minutes
  ip=$(curl -s -x "http://${PROXY_USER}:${PROXY_PASS}@${PROXY_HOST}:7777" https://icanhazip.com)
  if [ "$ip" != "$last" ]; then
    echo "$(( ($(date +%s) - start) / 60 ))m  $ip"; last="$ip"
  fi
  sleep 20
done

On Essential, expect one line at 0m and another close to 120m, which is the clamp showing up where the docs say it will. Premium should print one line and then nothing for the rest of the 125 minutes. If the address changes sooner than that on either pool, the time it changed is your real number, whatever the spec sheet says.

Proxyway's data shows why that matters. Across its 30-minute window most networks held their IPs for a surprisingly long time, but the vast majority of Byteful's sessions ended at around 10 minutes, even though its documentation said they'd last as long as possible. The hold it measured was a third of the window.

Ceilings also differ a lot between vendors. Oxylabs publishes sticky residential sessions of up to 24 hours, which matches our Premium, and IPRoyal publishes up to 7 days (residential page, read 2026-11-06). If your stateful work runs for days, read our IPRoyal comparison before you build on us.

One instrumented run of your own flow decides it

At today's rate on the pricing page, the smallest Essential purchase buys roughly a third of a gigabyte. That's far too little for real volume and plenty for both scripts above plus one instrumented pass of your own flow.

Run the twenty-request count on a bare line and on a ~30 line, then put your real flow through once with exit IPs logged and a clock running. If it fails at an IP change you need sticky, and the length of the longest stateful stretch, under or over 120 minutes, tells you whether Essential holds it or you need Premium or Mobile.

Try it on your own targets

Start small, then measure.

Top up a wallet from $0.50 and point it at your own targets, or try the free trial first.

See pricing