[{"data":1,"prerenderedAt":21},["ShallowReactive",2],{"blog:post:en:timed-proxy-rotation-for-multi-account-scraping":3},{"slug":4,"lang":5,"title":6,"summary":7,"date":8,"tags":9,"tag_slugs":14,"thumbnail_url":17,"translations":18,"body":19,"asset_base":20},"timed-proxy-rotation-for-multi-account-scraping","en","Timed Proxy Rotation for Multi‑Account Scraping","Use timed rotation modes to schedule predictable IP changes and manage multiple accounts without getting blocked.","2026-10-30",[10,11,12,13],"proxy rotation","multi-account","python","session management",[15,11,12,16],"proxy-rotation","session-management","https://blog-api.ro-proxy.com/api/blog/posts/timed-proxy-rotation-for-multi-account-scraping/thumbnail.svg?lang=en",[5],"## Introduction\n\nWhen you run scrapers for several user accounts—think social media managers, price‑monitoring bots, or ad‑verification tools—keeping a steady flow of requests while staying under rate limits can be tricky. Sticky sessions keep the same IP for the whole run, which is easy but can look suspicious. Per‑request rotation (a new IP every call) is the safest but often overkill and wasteful. A middle ground—**timed rotation**—lets you change the IP after a configurable interval, giving you a regular cadence that mimics natural user behavior while still preserving session state between calls.\n\nThis guide shows you how to set up a timed rotation for RoProxy sessions in a Python scraper, why it matters for multi‑account workflows, and how to troubleshoot common issues.\n\n## Why Timed Rotation Beats Sticky or Per‑Request\n\n- **Predictable cadence** – You decide when the IP flips (e.g., every 30 seconds). This makes it easier to reason about request bursts and to align with rate‑limit windows.\n- **Session continuity** – Between rotations the same credentials stay attached, so cookies, authentication tokens, and logged‑in state survive. That’s essential for accounts that require login persistence.\n- **Resource efficiency** – You avoid the overhead of creating a brand‑new TCP connection for each request, which saves CPU and reduces latency compared with per‑request rotation.\n- **Control over fingerprint** – By keeping the same IP for a few minutes you can still rotate headers and user‑agents to avoid fingerprinting while not over‑exposing the pool.\n\n## RoProxy Session Basics\n\nRoProxy offers rotating proxy **sessions** that you authenticate with a username/password pair. Each session can be configured with a rotation mode: **sticky**, **timed**, or **per‑request** (Business plan only). In timed mode the service will exchange the underlying IP after the interval you specify, using the same credentials.\n\nTo interact with the service you use two public endpoints:\n\n- `GET https://backend-api.ro-proxy.com/api/session` – lists your sessions.\n- `POST https://backend-api.ro-proxy.com/api/session/{SESSION_ID}/rotate` – triggers an immediate IP change.\n\nAll communication is protected with an `Authorization: Bearer API_KEY` header. The API key is separate from the session credentials and is used only for management calls.\n\n## Configuring a Timed Session for Multi‑Account Scraping\n\nBefore you can rotate, you need a session ID that is already in timed mode. The RoProxy dashboard (or the API) lets you create sessions and set the rotation interval. For the purpose of this article we assume you already have:\n\n- `SESSION_ID` – the identifier for your timed session.\n- `API_KEY` – your bearer token for the management API.\n\nWith those in hand you can write a small helper that periodically calls the rotate endpoint. The helper should run in a background thread or as a scheduled job (e.g., APScheduler) so that the scraper can continue using the same proxy URL without manual intervention.\n\n**Proxy URL format** – When you need to use the session in a HTTP client you build a URL like:\n\n```\nhttp://USERNAME:PASSWORD@GATEWAY_HOST:HTTP_PORT\n```\n\nAll placeholders (`GATEWAY_HOST`, `HTTP_PORT`, `USERNAME`, `PASSWORD`) are supplied by RoProxy after the session is created. The same credentials also work for HTTPS, and on Pro/Business plans a SOCKS5 endpoint (`GATEWAY_HOST:SOCKS5_PORT`) is available if your library supports it.\n\n## Python Example: Using Timed Rotation in a Real Scraper\n\nBelow is a complete, runnable pattern that:\n\n1. Starts a background scheduler that calls the rotate endpoint every 30 seconds.\n2. Uses `requests.Session` with the proxy URL built from the placeholders.\n3. Performs a sample GET to `https://api.ipify.org?format=json` to verify the exit IP after each rotation.\n4. Handles errors gracefully (e.g., network glitches, API failures) without breaking the scraper.\n\n```python\nimport time\nimport threading\nimport requests\nimport json\nfrom schedule import Schedule\n\n# ---------- Configuration ----------\nAPI_KEY = \"API_KEY\"               # Your RoProxy management key\nSESSION_ID = \"SESSION_ID\"         # The timed session you created\nROTATE_INTERVAL = 30              # seconds between rotations\n\nGATEWAY_HOST = \"GATEWAY_HOST\"     # supplied by RoProxy\nHTTP_PORT = \"HTTP_PORT\"            # supplied by RoProxy\nUSERNAME = \"USERNAME\"             # supplied by RoProxy\nPASSWORD = \"PASSWORD\"             # supplied by RoProxy\n\nPROXY_URL = f\"http://{USERNAME}:{PASSWORD}@{GATEWAY_HOST}:{HTTP_PORT}\"\n\n# ---------- Rotation Helper ----------\ndef rotate_ip():\n    url = f\"https://backend-api.ro-proxy.com/api/session/{SESSION_ID}/rotate\"\n    headers = {\"Authorization\": f\"Bearer {API_KEY}\"}\n    try:\n        resp = requests.post(url, headers=headers, timeout=10)\n        resp.raise_for_status()\n        print(f\"[ROTATE] IP refreshed at {time.isoformat()}\")\n    except Exception as exc:\n        print(f\"[ROTATE ERROR] {exc}\")\n\n# Schedule periodic rotations\nSchedule().every(ROTATE_INTERVAL).seconds.do(rotate_ip)\n\n# ---------- Verification Helper ----------\ndef check_exit_ip(session):\n    # Use a lightweight endpoint that returns the public IP\n    resp = session.get(\"https://api.ipify.org?format=json\", timeout=10)\n    resp.raise_for_status()\n    return resp.json()\n\n# ---------- Main Scraper Loop ----------\nif __name__ == \"__main__\":\n    # Create a requests session that will use the proxy\n    session = requests.Session()\n    session.proxies.update({\"http\": PROXY_URL, \"https\": PROXY_URL})\n\n    print(\"[START] Timed rotation scraper started\")\n    while True:\n        # Perform your real scraping logic here\n        # For demo we just verify the exit IP\n        try:\n            ip_info = check_exit_ip(session)\n            print(f\"[IP] Current exit IP: {ip_info.get('ip')}\")\n        except Exception as exc:\n            print(f\"[IP CHECK ERROR] {exc}\")\n\n        # Run any pending scheduled jobs (rotation)\n        Schedule().run_pending()\n\n        # Wait a bit before the next iteration\n        time.sleep(5)\n```\n\n### How the Pieces Fit Together\n\n1. **Background rotation** – `schedule` (or APScheduler) runs `rotate_ip()` every `ROTATE_INTERVAL`. The function POSTs to RoProxy’s rotate endpoint, forcing a new underlying IP while keeping the same `USERNAME`/`PASSWORD` pair.\n2. **Proxy reuse** – The `PROXY_URL` never changes; the underlying TCP connection is dropped and re‑established by the proxy gateway after each rotation. This means your Python `requests.Session` can keep cookies, headers, and even a WebSocket open without explicit reconnection logic.\n3. **Verification** – `check_exit_ip` hits a public IP service. Because the request goes through the proxy, you can confirm that the rotation actually took effect.\n4. **Resilience** – If the rotation call fails, the scraper continues. You can add exponential back‑off or alerting if you need stricter guarantees.\n\n## Best Practices and Common Pitfalls\n\n- **Keep the interval realistic** – Too short (e.g., 5 seconds) may cause the proxy to throttle you; too long (e.g., 5 minutes) may look like a single user. 20‑60 seconds is a common sweet spot for multi‑account tasks.\n- **Thread safety** – The rotation job runs in a separate thread. Ensure that any shared state (e.g., a global session) is protected with a `threading.Lock` if you ever mutate it from both threads.\n- **Handle proxy‑specific errors** – A 407 Authentication Required often means the proxy credentials expired. Refresh them by creating a new session or contacting support.\n- **Log rotation events** – Include the new IP (if you can retrieve it) in your logs. This makes debugging easier when you hit rate limits or CAPTCHAs.\n- **Respect target rate limits** – Even with timed rotation, you still need to stay under the target site’s per‑minute or per‑hour caps. Use a token‑bucket or circuit‑breaker pattern in your scraper to stay safe.\n- **Test locally** – Before you push to production, spin up a small test that prints the IP after each rotation. Verify that the IP actually changed and that the session still works (cookies, auth tokens).\n\n## Conclusion\n\nTimed rotation gives you a balanced approach to IP management: you keep session continuity while still refreshing your fingerprint at a predictable cadence. By leveraging RoProxy’s timed mode and a simple background scheduler you can build robust multi‑account scrapers that stay under the radar and avoid common pitfalls like sticky IP detection or per‑request overhead.\n\nGive the pattern above a try, adjust the interval to match your target’s rate‑limit windows, and monitor the exit IP to confirm each rotation works as expected. When you’re ready to scale, consider integrating circuit breakers and exponential back‑off to keep your scraper resilient under load.\n\nHappy scraping with RoProxy!\n","https://blog-api.ro-proxy.com/api/blog/posts/timed-proxy-rotation-for-multi-account-scraping/assets",1793344290522]