
Building Resilient Web Scrapers: Retry, Circuit Breaker, and Fallback Patterns
Learn how to add retry logic, circuit breakers, and fallbacks to your scraping pipelines to handle transient failures and maintain data collection reliability.
AlterLab handles this automatically — scrape any URL with one API call. No infrastructure required.
Try it freeTL;DR
Add retry logic with exponential backoff and jitter, implement a circuit breaker to halt requests after repeated failures, and define fallbacks like cached data or alternative endpoints. These patterns keep your scraping pipeline reliable despite transient network issues, rate limits, or temporary blocks.
Why Resilience Matters in Scraping
Web scraping pipelines encounter intermittent failures: network timeouts, HTTP 5xx responses, rate limits, or temporary anti-bot challenges. Without handling these, a single hiccup can halt an entire data collection job, leading to stale datasets and wasted compute. Resilience patterns isolate failures, allow automatic recovery, and preserve throughput.
Retry Strategies: Exponential Backoff with Jitter
A basic retry simply repeats the request immediately, which can worsen load on a struggling server. Instead, use exponential backoff: wait 1s, then 2s, then 4s, etc., up to a maximum delay. Adding jitter (random delay) prevents thundering herd problems when many clients recover simultaneously.
Python SDK Example
import time
import random
import alterlab
client = alterlab.Client("YOUR_API_KEY")
def scrape_with_retry(url, max_attempts=5):
attempt = 0
while attempt < max_attempts:
try:
response = client.scrape(url)
if response.status_code < 500:
return response
except alterlab.APIError as exc:
if exc.status_code >= 500:
pass # treat as retryable
else:
raise # client errors (4xx) are not retried
attempt += 1
delay = (2 ** attempt) + random.uniform(0, 1) # exponential backoff + jitter
time.sleep(delay)
raise RuntimeError(f"Failed to scrape {url} after {max_attempts} attempts")
# usage
data = scrape_with_retry("https://example.com/public-data")
print(data.json)cURL Example with Retry Header
curl -X POST https://api.alterlab.io/v1/scrape \
-H "X-API-Key: YOUR_KEY" \
-H "Retry-After: 1" \
-d '{"url": "https://example.com/public-data", "max_retries": 4}'Note: The AlterLab API honors the
Retry-Afterheader and respects themax_retriesparameter, applying exponential backoff internally when enabled.
Circuit Breaker Pattern
A circuit breaker tracks consecutive failures. After a threshold (e.g., five failures), it trips and blocks further requests for a cooldown period (e.g., 30 seconds). During the cooldown, calls fail fast, saving resources and allowing the remote service to recover. After the cooldown, a limited trial request tests if the service is healthy.
Implementation Sketch
import time
from enum import Enum
class State(Enum):
CLOSED = 0
OPEN = 1
HALF_OPEN = 2
class CircuitBreaker:
def __init__(self, fail_threshold=5, timeout=30):
self.fail_threshold = fail_threshold
self.timeout = timeout
self.fail_count = 0
self.state = State.CLOSED
self.last_failure_time = None
def call(self, func, *args, **kwargs):
if self.state == State.OPEN:
if time.time() - self.last_failure_time > self.timeout:
self.state = State.HALF_OPEN
else:
raise RuntimeError("Circuit breaker is OPEN")
try:
result = func(*args, **kwargs)
self.on_success()
return result
except Exception as exc:
self.on_failure()
raise exc
def on_success(self):
self.fail_count = 0
self.state = State.CLOSED
def on_failure(self):
self.fail_count += 1
self.last_failure_time = time.time()
if self.fail_count >= self.fail_threshold:
self.state = State.OPENIntegrate the breaker around your scrape call:
breaker = CircuitBreaker(fail_threshold=4, timeout=20)
def safe_scrape(url):
return breaker.call(scrape_with_retry, url)
# usage
try:
data = safe_scrape("https://example.com/public-data")
except RuntimeError as err:
print("Scrape unavailable:", err)Fallbacks: Cached Data and Alternative Endpoints
When the circuit breaker is open or retries exhaust, serve stale data from a cache or query a mirror site. This ensures downstream processes continue receiving data, albeit possibly less fresh.
Simple Cache Fallback
import json
import os
from datetime import datetime, timedelta
CACHE_DIR = "./scrape_cache"
CACHE_TTL = timedelta(hours=6)
def get_cached(url):
path = os.path.join(CACHE_DIR, hash(url) + ".json")
if not os.path.exists(path):
return None
with open(path) as f:
entry = json.load(f)
if datetime.fromisoentry["fetched"] + CACHE_TTL < datetime.utcnow():
return None
return entry["data"]
def save_cache(url, data):
os.mWas this article helpful?
Frequently Asked Questions
Related Articles

How to Scrape Glassdoor Interviews Data: Complete Guide for 2026
Learn to scrape Glassdoor Interviews for job market insights using AlterLab's API. Python/Node.js examples, Cortex extraction, pricing, and compliance best practices.
Herald Blog Service

Handling Dynamic Pagination in Modern Web Applications
Learn how to navigate dynamic pagination in modern web applications using API interception, headless browsers, and automated scraping workflows.
Herald Blog Service

How to Scrape LoopNet Data: Complete Guide for 2026
Learn how to scrape LoopNet for real-estate data using AlterLab's API with Python and Node.js. Handle anti-bot protections and extract structured data efficiently.
Herald Blog Service
Popular Posts
Recommended
Newsletter
Scraping insights and API tips. No spam.
Recommended Reading

How to Scrape AliExpress: Complete Guide for 2026

Why Your Headless Browser Gets Detected (and How to Fix It)

AlterLab vs Firecrawl: Which Scraping API Is Better in 2026?

How to Scrape Twitter/X Data: Complete Guide for 2026

How to Scrape Cloudflare-Protected Sites in 2026
Stay in the Loop
Get scraping insights, API tips, and platform updates. No spam — we only send when we have something worth reading.
Explore AlterLab
Anti-Bot Handling API
Automatic challenge handling for protected sites — works out of the box.
JavaScript Rendering API
Render SPAs and dynamic content with headless Chromium.
Pricing
5-tier pricing from $0.0002/page. 5,000 free requests to start.
Documentation
API reference, SDKs, quickstart guides, and tutorials.
Web Scraping API Resources
Part of the Web Scraping API Documentation cluster
Complete API reference with 5-tier auto-escalation — Curl to challenge resolution.
Pillar pageConfigure Tier 4 browser rendering for SPAs and dynamic content.
Scrape pages behind login using session management.
Real success rates and cost data across all 5 tiers.
MCP Server, Python SDK, and Firecrawl-compatible API for AI agent workflows.