← Blog · · 5 min read

Reliable Proxy Requests: Retries, Backoff, and Session Recovery

Residential proxy clients operate across several independent systems: your application, the proxy endpoint, a residential device, the public internet, and the destination. A request can fail at any boundary, and repeating every failure immediately is neither reliable nor responsible.

A better design classifies failures, retries only safe operations, spaces attempts with backoff, and treats sticky-session recovery as a workflow decision rather than a transport detail.

Start with idempotency

Before writing retry code, ask whether the operation is safe to repeat. A public GET that only reads a page is commonly retryable. A request that submits a form, changes account state, or triggers a purchase may not be.

Do not use a generic retry wrapper around every HTTP method. Mark jobs as retryable based on their semantics, and use an idempotency mechanism supplied by the destination when one is available.

For public-data collection, a useful unit of work contains:

  • the normalized URL and target country;
  • the parser and request-policy version;
  • a maximum attempt count;
  • a deadline for the whole job, not only each socket operation;
  • an output key that prevents duplicate storage.

Classify the failure before retrying

Not every error deserves another residential exit.

Authentication failures

An HTTP 407 Proxy Authentication Required response points to credentials or proxy configuration. Retrying the same invalid values wastes time and can hide a deployment problem. Stop the job, redact credentials from logs, and alert on the configuration error.

Destination rate limits

An HTTP 429 Too Many Requests response comes from the destination’s policy. Respect Retry-After when supplied, lower concurrency, and reconsider the collection schedule. Rotating IPs is not a substitute for respecting a site’s rate limits.

Destination client errors

Most other 4xx responses are stable for the same request: 404 often means the resource is absent, while 401 or 403 can reflect destination authorization or policy. Preserve the status and avoid blindly retrying it.

Transport and server failures

Connection resets, timeouts, and some 5xx responses can be transient. These are candidates for bounded retries when the operation is idempotent. Use separate connect and total deadlines so a stalled job cannot occupy a worker indefinitely.

Use exponential backoff with jitter

Backoff prevents many workers from retrying at the same instant. Jitter adds a small random variation so synchronized failures do not become synchronized retry bursts.

This Python example retries only selected transport errors and server responses. It leaves destination-specific decisions to the caller:

import random
import time

import requests


RETRYABLE_STATUS = {500, 502, 503, 504}


def get_with_backoff(url, proxies, attempts=4):
    for attempt in range(attempts):
        try:
            response = requests.get(
                url,
                proxies=proxies,
                timeout=(10, 30),
            )

            if response.status_code not in RETRYABLE_STATUS:
                return response
        except (requests.ConnectTimeout, requests.ReadTimeout,
                requests.ConnectionError):
            if attempt == attempts - 1:
                raise

        if attempt == attempts - 1:
            break

        base_seconds = 0.5 * (2 ** attempt)
        time.sleep(base_seconds + random.uniform(0, base_seconds / 2))

    raise RuntimeError("request exhausted its retry budget")

Choose timeouts and attempt counts from your workload and observations. PacketStream does not publish a universal latency or reliability promise, and a setting that works for one destination may be wrong for another.

Understand what a retry does to rotation

PacketStream automatic rotation selects a residential exit for each new proxy connection. If a retry creates a new connection, it may use a different exit. That is useful for independent read requests, but it can change the meaning of a stateful workflow.

Keep connection behavior explicit:

  • independent job: a retry may use a newly selected residential exit;
  • country-targeted job: every retry must preserve the same country suffix;
  • sticky workflow: every step uses the same session ID until success or terminal failure.

Do not assume that creating a new HTTP request creates a new proxy connection. Connection pools can reuse sockets. Configure and test the transport used in production.

Recover sticky sessions at the workflow boundary

PacketStream sticky sessions can keep the same exit for up to 60 minutes. If the associated Packeter disconnects, the session fails.

When that happens, avoid changing the session ID inside an arbitrary step. Instead:

  1. stop the current workflow;
  2. determine whether its earlier actions are safe to repeat;
  3. clear destination cookies or state only when the workflow requires a fresh start;
  4. create a new non-sensitive session ID;
  5. restart from a defined checkpoint.

For a read-only sequence, restarting from step one may be straightforward. For a state-changing sequence, human review or destination-supported idempotency may be necessary.

Put limits around the entire system

Retries multiply traffic and bandwidth. Four attempts across three internal layers can create far more work than the top-level limit suggests. Choose one layer to own the retry budget and make inner libraries return clear errors.

Add guardrails:

  • a maximum attempts count per job;
  • a total elapsed-time deadline;
  • global and per-destination concurrency limits;
  • circuit breaking when a destination or configuration fails repeatedly;
  • structured logs without proxy credentials;
  • counters for attempts, final outcomes, countries, and status classes.

Store enough context to diagnose patterns, but avoid collecting unnecessary personal data. Exit IP and approximate geography are usually sufficient for proxy-path diagnostics.

Reliability means predictable failure

A reliable scraper is not one that retries until something works. It is one that produces a correct result or a well-labeled failure within a bounded amount of time.

Start with the recommended HTTPS residential proxy endpoint, classify errors, respect destination controls, and make session recovery part of the job’s state machine. That produces a system that is easier to operate and safer to scale.