Explainers

Rate Limiting CAPTCHA Solving Workflows

Sending too many requests too fast triggers blocks, bans, and wasted CAPTCHA solves. Smart rate limiting keeps your automation running long-term.


Why Rate Limiting Matters

Problem Cause Impact
IP blocked Too many requests/minute Automation stops
CAPTCHA difficulty increases High-frequency patterns detected Slower solves
Token rejected after solve Site flagged the session Wasted money
Account banned Abnormal behavior patterns Permanent block

Token Bucket Rate Limiter

import time
import threading


class TokenBucketLimiter:
    """Rate limiter using token bucket algorithm."""

    def __init__(self, rate, burst=1):
        """
        Args:
            rate: Requests per second allowed.
            burst: Maximum burst size.
        """
        self.rate = rate
        self.burst = burst
        self.tokens = burst
        self.last_refill = time.monotonic()
        self._lock = threading.Lock()

    def acquire(self, timeout=None):
        """Wait until a token is available."""
        deadline = time.monotonic() + timeout if timeout else None

        while True:
            with self._lock:
                self._refill()
                if self.tokens >= 1:
                    self.tokens -= 1
                    return True

            if deadline and time.monotonic() >= deadline:
                return False

            # Wait for next token
            with self._lock:
                wait_time = (1 - self.tokens) / self.rate
            time.sleep(min(wait_time, 0.1))

    def _refill(self):
        """Add tokens based on elapsed time."""
        now = time.monotonic()
        elapsed = now - self.last_refill
        self.last_refill = now
        self.tokens = min(self.burst, self.tokens + elapsed * self.rate)


# 2 requests per second, burst of 5
limiter = TokenBucketLimiter(rate=2, burst=5)


def rate_limited_solve(solver, params):
    """Solve CAPTCHA with rate limiting."""
    limiter.acquire()
    return solver.solve(params)

Per-Domain Rate Limiter

Different sites need different rates:

from collections import defaultdict
from urllib.parse import urlparse


class DomainRateLimiter:
    """Apply different rate limits per target domain."""

    DEFAULT_DELAY = 5.0  # seconds between requests to same domain

    DOMAIN_DELAYS = {
        "example.com": 3.0,
        "api.example.com": 1.0,
    }

    def __init__(self):
        self._last_request = defaultdict(float)
        self._lock = threading.Lock()

    def wait(self, url):
        """Wait appropriate time before requesting this domain."""
        domain = urlparse(url).netloc
        delay = self.DOMAIN_DELAYS.get(domain, self.DEFAULT_DELAY)

        with self._lock:
            elapsed = time.time() - self._last_request[domain]
            if elapsed < delay:
                sleep_time = delay - elapsed
                time.sleep(sleep_time)
            self._last_request[domain] = time.time()


domain_limiter = DomainRateLimiter()


def safe_request(url, **kwargs):
    """Make rate-limited request."""
    domain_limiter.wait(url)
    return requests.get(url, **kwargs)

Jittered Delays

Fixed delays create detectable patterns. Add randomness:

import random
import time


def human_delay(base_seconds=3.0, jitter=0.5):
    """Sleep with human-like randomness."""
    delay = base_seconds + random.uniform(-jitter * base_seconds, jitter * base_seconds)
    time.sleep(max(0.5, delay))


def exponential_backoff_delay(attempt, base=2.0, max_delay=60.0):
    """Exponential backoff with jitter for retries."""
    delay = min(base * (2 ** attempt), max_delay)
    jittered = delay * random.uniform(0.5, 1.5)
    time.sleep(jittered)

Sliding Window Counter

Track request counts over time:

import time
from collections import deque
import threading


class SlidingWindowLimiter:
    """Count requests in a rolling time window."""

    def __init__(self, max_requests, window_seconds):
        self.max_requests = max_requests
        self.window = window_seconds
        self.timestamps = deque()
        self._lock = threading.Lock()

    def can_proceed(self):
        """Check if a new request is allowed."""
        with self._lock:
            now = time.time()
            cutoff = now - self.window

            # Remove old timestamps
            while self.timestamps and self.timestamps[0] < cutoff:
                self.timestamps.popleft()

            if len(self.timestamps) < self.max_requests:
                self.timestamps.append(now)
                return True
            return False

    def wait_and_proceed(self):
        """Block until request is allowed."""
        while not self.can_proceed():
            time.sleep(0.5)


# Max 10 CAPTCHA solves per minute
solve_limiter = SlidingWindowLimiter(max_requests=10, window_seconds=60)


def limited_solve(solver, params):
    """Solve with sliding window rate limit."""
    solve_limiter.wait_and_proceed()
    return solver.solve(params)

Adaptive Rate Limiting

Automatically slow down when detecting problems:

class AdaptiveRateLimiter:
    """Adjust rate based on response signals."""

    def __init__(self, initial_delay=3.0, min_delay=1.0, max_delay=30.0):
        self.delay = initial_delay
        self.min_delay = min_delay
        self.max_delay = max_delay
        self._lock = threading.Lock()

    def report_success(self):
        """Speed up slightly after success."""
        with self._lock:
            self.delay = max(self.min_delay, self.delay * 0.95)

    def report_block(self):
        """Slow down after being blocked."""
        with self._lock:
            self.delay = min(self.max_delay, self.delay * 2.0)

    def report_captcha_harder(self):
        """Slow down when CAPTCHA difficulty increases."""
        with self._lock:
            self.delay = min(self.max_delay, self.delay * 1.5)

    def wait(self):
        """Wait the current delay with jitter."""
        with self._lock:
            delay = self.delay
        jittered = delay * random.uniform(0.8, 1.2)
        time.sleep(jittered)


rate = AdaptiveRateLimiter(initial_delay=3.0)

# In your automation loop:
# rate.wait()
# result = make_request()
# if result.status_code == 429:
#     rate.report_block()
# elif "captcha" in result.text and not expected:
#     rate.report_captcha_harder()
# else:
#     rate.report_success()

Use Case Requests/min Delay Between
Price monitoring 5-10 6-12 seconds
Data collection 10-20 3-6 seconds
QA testing 2-5 12-30 seconds
Form testing 1-3 20-60 seconds

FAQ

Does rate limiting increase costs?

No. It actually reduces costs by preventing wasted CAPTCHA solves that would be rejected by the target site.

Should I rate limit CaptchaAI API calls too?

CaptchaAI handles high throughput, but for ERROR_NO_SLOT_AVAILABLE, implement backoff. Rate limiting applies mainly to the target site, not the CaptchaAI API.

How do I know if I'm being detected?

Signs include: more CAPTCHAs appearing, CAPTCHA difficulty increasing, HTTP 429 responses, session termination, or IP blocks.



Build sustainable automation — start with CaptchaAI.

Discussions (0)

No comments yet.

Related Posts

Reference CAPTCHA Solving Performance by Region: Latency Analysis
Analyze how geographic region affects Captcha AI solve times — network latency, proxy location, and optimization strategies for global deployments.

Analyze how geographic region affects Captcha AI solve times — network latency, proxy location, and optimizati...

Python Automation All CAPTCHA Types
Apr 05, 2026
Explainers DNS Resolution Impact on CAPTCHA API Performance
Understand how DNS resolution affects CAPTCHA API call latency and to optimize with DNS caching, pre-resolution, and DNS-over-HTTPS.

Understand how DNS resolution affects CAPTCHA API call latency and learn to optimize with DNS caching, pre-res...

Python Automation All CAPTCHA Types
Apr 03, 2026
Troubleshooting CaptchaAI API Rate Limiting: Handling 429 Responses
Handle Captcha AI API rate limits and 429 responses.

Handle Captcha AI API rate limits and 429 responses. Implement exponential backoff, request throttling, and qu...

Python Automation All CAPTCHA Types
Apr 01, 2026
DevOps & Scaling Auto-Scaling CAPTCHA Solving Workers
Build auto-scaling CAPTCHA solving workers that adjust capacity based on queue depth, balance, and solve rates.

Build auto-scaling CAPTCHA solving workers that adjust capacity based on queue depth, balance, and solve rates...

Python Automation All CAPTCHA Types
Mar 23, 2026
Tutorials CAPTCHA Solving Throughput: How to Process 10,000 Tasks per Hour
Architect a CAPTCHA solving pipeline that processes 10,000 tasks per hour using Captcha AI with async Python, connection pooling, and queue-based distribution.

Architect a CAPTCHA solving pipeline that processes 10,000 tasks per hour using Captcha AI with async Python,...

Python Automation All CAPTCHA Types
Mar 13, 2026
Explainers User-Agent Management for CAPTCHA Solving Workflows
Manage user-agent strings for CAPTCHA solving workflows.

Manage user-agent strings for CAPTCHA solving workflows. Avoid detection with proper UA rotation, consistency,...

Python Automation Web Scraping
Mar 09, 2026
DevOps & Scaling Horizontal Scaling CAPTCHA Solving Workers: When and How
Scale CAPTCHA solving horizontally — identify bottlenecks, add workers dynamically, auto-scale based on queue depth, and manage costs with Captcha AI.

Scale CAPTCHA solving horizontally — identify bottlenecks, add workers dynamically, auto-scale based on queue...

Python Automation All CAPTCHA Types
Mar 07, 2026
Tutorials Rate-Limited Concurrency: Token Bucket for CAPTCHA API Calls
Implement a token bucket rate limiter for CAPTCHA API calls — control request rates, prevent throttling, and manage Captcha AI API consumption budgets.

Implement a token bucket rate limiter for CAPTCHA API calls — control request rates, prevent throttling, and m...

Python Automation All CAPTCHA Types
Feb 26, 2026
Tutorials Rate Limiting Your Own CAPTCHA Solving Requests
Implement client-side rate limiting for Captcha AI API calls — token bucket, sliding window, and per-key limits to prevent overuse and control costs.

Implement client-side rate limiting for Captcha AI API calls — token bucket, sliding window, and per-key limit...

Python Automation All CAPTCHA Types
Feb 26, 2026
Troubleshooting CAPTCHA Solve Rate Drops: Performance Regression Diagnosis
Diagnose sudden drops in CAPTCHA solve rates — identify whether the issue is your code, proxy, target site changes, or Captcha AI service conditions.

Diagnose sudden drops in CAPTCHA solve rates — identify whether the issue is your code, proxy, target site cha...

Python Automation All CAPTCHA Types
Feb 17, 2026
Explainers reCAPTCHA v2 Invisible: Trigger Detection and Solving
Detect and solve re CAPTCHA v 2 Invisible challenges with Captcha AI — identify triggers, extract parameters, and handle auto-invoked CAPTCHAs.

Detect and solve re CAPTCHA v 2 Invisible challenges with Captcha AI — identify triggers, extract parameters,...

Python Automation reCAPTCHA v2
Apr 07, 2026
Explainers How BLS CAPTCHA Works: Grid Logic and Image Selection
Deep dive into BLS CAPTCHA grid logic — how images are arranged, how instructions map to selections, and how Captcha AI processes BLS challenges.

Deep dive into BLS CAPTCHA grid logic — how images are arranged, how instructions map to selections, and how C...

Automation BLS CAPTCHA
Apr 09, 2026
Explainers How BLS CAPTCHA Works
Understand how BLS CAPTCHA works on visa appointment systems.

Understand how BLS CAPTCHA works on visa appointment systems. Learn about its image selection mechanism, how i...

Automation BLS CAPTCHA
Apr 06, 2026