← all guides

What happens when a proxy rotates mid request

The request that started on one IP and finished on another

If you have run a scraper long enough on a rotating proxy pool, you have seen it: a request goes out, and somewhere between the TCP handshake and the final byte of the response, the exit IP changes. The response comes back fine. The status code is 200. But your logs show the connection opened on 103.x.x.11 and the target site’s own logs (if you ever get to see them) would show the request landing from 103.x.x.47. Nothing crashed. Nothing errored. But two different IPs touched the same logical request, and that has consequences you may not notice until much later.

This is not a bug in your code. It is a property of how rotation is implemented at the network layer, and understanding it changes how you should build a scraper that uses rotating IPs.

Rotation happens below your application, not inside it

When people say “rotating proxy,” they usually mean one of two different things, and the difference matters a lot here.

The first is session-based rotation: your proxy provider assigns you an IP (or a gateway session tied to an IP) for a fixed window, commonly somewhere between one and thirty minutes depending on the provider, and every request you make during that window goes out through the same exit node. When the window closes, the next request gets a new IP. This is the mode you want for anything multi-step: a login, a cart flow, a paginated crawl where the site expects the same visitor to keep coming back.

The second is per-request rotation: the gateway picks a fresh exit IP for every single outbound connection, with no session concept at all. This is common with datacenter pools and with residential providers running a “rotating” endpoint rather than a “sticky” one.

Mid-request rotation, the thing this article is actually about, is a different and narrower failure mode that can happen inside either model. It is not the gateway deciding “this session is over, next request gets a new IP.” It is the exit IP changing while a single request is still in flight. That happens because most rotating gateways are not a single proxy machine, they are a pool of exit nodes behind a load balancer or a session broker, and that broker makes its exit-node decision on a timer or a health check that is not synchronized with your request lifecycle. If a node health check fails, or a sticky-session timer expires at the millisecond your request happens to still be open, or the backing mobile/residential device drops its carrier connection and gets reassigned, the gateway can hand the rest of your connection to a different exit node without your client ever seeing an error.

TCP does not enforce IP continuity for you at the application layer the way you might assume. Your scraper opened a socket to the proxy, and as far as your HTTP client is concerned, one socket, one IP. But the proxy itself may be relaying that traffic through a chain where the actual outbound leg to the target server was reassigned mid-stream, especially over HTTP/1.1 keep-alive connections or long-lived HTTP/2 connections where the proxy is multiplexing several of your requests over one upstream link and swaps that upstream link between them.

What it actually does to a request

Three outcomes cover almost everything you will see:

The request completes, but as two different visitors. This is the most common and the most dangerous because it looks like a success. Your scraper gets a 200 and valid HTML. But if the target site does any kind of session or fingerprint continuity check, the request that opened the TLS handshake from IP A and the request that a WAF or fraud system attributes to IP B on the response side are now split across two identities. For a single stateless page fetch this rarely matters. For anything involving a login cookie, a CSRF token bound to a session, or a cart, this can produce a silent logout, a stale-cart response, or a page that renders as if you were never authenticated, even though the status code says everything is fine.

The connection resets. If the gateway tears down the old upstream socket to reassign it rather than trying to hand off a live stream, you get a connection reset or a truncated response partway through the body. This is the version that is at least honest: your HTTP client raises an error, your retry logic (you have retry logic, right) fires, and you get a clean second attempt on a new IP.

The TLS handshake and the HTTP request land on different exit paths. This is rarer and mostly shows up with proxies doing TLS termination and re-encryption rather than pure TCP tunneling. The client-facing TLS session negotiates against one identity, then the proxy’s internal routing sends the decrypted HTTP request out through a different exit node than the one implied by the handshake. From your side it is invisible. From the target’s side, if they are doing TLS fingerprinting alongside IP-based checks (JA3/JA4 style fingerprinting is common in modern bot detection stacks), this creates a mismatch between the network fingerprint and the IP reputation the request arrives with, which is exactly the kind of inconsistency detection systems are built to flag. This is worth understanding defensively: it is not something you can engineer your way around from the client side, because the split happens inside infrastructure you do not control. It is a reason to pick proxy infrastructure that documents how it handles TLS and connection reuse, and to test rather than assume.

Why sticky sessions exist, and why they are not a full fix

Providers sell “sticky” or “session” proxies specifically to reduce this exposure: pin one exit IP to one session ID for N minutes, and route every request tagged with that session ID to the same node. This solves the common case, a login flow or a multi-page crawl where you need the same IP across five or six sequential requests.

It does not solve the in-flight case described above, because the sticky guarantee is about which IP gets picked for the next request, not about protecting a request that is already open when the underlying node has a problem. A sticky session can still hand you a reset mid-download if the physical device behind that session (this matters a lot for mobile and residential pools, where the “device” is a real phone or home connection) drops off the network. Stickiness reduces how often rotation happens under you; it does not remove the possibility.

Designing your scraper around it

None of this is a reason to distrust rotating proxies. It is a reason to write a scraper that assumes the network under it is not perfectly stable, because it isn’t, on any provider.

A few concrete things that actually help:

  • Treat every response as unverified until you check it. Don’t just check the status code. If you are following a login or session flow, verify the response body actually reflects the expected identity (the account name is present, the cart total matches what you expect) before trusting it. A 200 with a logged-out page is a symptom of exactly this problem.
  • Use short, single-purpose connections for stateless fetches. If you only need one page and don’t need session continuity, don’t reuse a keep-alive connection across many unrelated requests through the same proxy socket. Shorter-lived connections give the gateway less time in which a mid-flight reassignment can happen.
  • Build retries that assume a full request may need to restart, not resume. A truncated body should not be patched together with a range request through the same rotating IP. Retry the whole request cleanly, ideally with the provider’s session-pinning feature if you need continuity, and expect a new IP if you don’t.
  • Log the exit IP per request, not per batch. If you’re only logging which proxy pool you used and not the literal exit IP on each request, you will not be able to tell a mid-request rotation apart from a normal 4xx error when you go back to debug it later.
  • Ask your provider directly how their gateway handles in-flight reassignment. This is a fair question to put to any proxy vendor before you commit real traffic to them, and a provider that can’t answer it clearly is telling you something about how mature their infrastructure is.

Mid-request rotation is a small, mostly invisible thing until it breaks a session flow you were relying on. Understanding it is less about avoiding it entirely, since it happens at a layer below your code, and more about building a scraper that notices when it happened and reacts correctly instead of quietly trusting a response that came from two different places.

If you want more breakdowns like this on how proxy infrastructure actually behaves under real scraping workloads, head back to the homepage.

Get new guides and videos first — join the Telegram channel.

proxies
Need proxies that survive the block wall?

Singapore Mobile Proxy runs real 4G/5G mobile IPs on rotating SIMs — the carrier-grade addresses most of these targets still trust.

see plans →
read on
More scraping guides

The rest of the field manual: target-site playbooks, library walkthroughs, provider reviews, and anti-bot troubleshooting.

browse all guides →