How to implement rate limiting in Python

A beginner-friendly Python rate limiter that throttles API calls and retries parsing tasks with exponential backoff.

Easy Python 3.9+ Aug 9, 2026 Reliability & rate limiting 15 views 0 copies

Python code

41 lines
Python 3.9+
import time
import random

class RateLimiter:
    def __init__(self, max_calls, per_seconds):
        self.max_calls = max_calls
        self.per_seconds = per_seconds
        self.timestamps = []
    
    def allow(self):
        now = time.time()
        self.timestamps = [t for t in self.timestamps if now - t < self.per_seconds]
        if len(self.timestamps) < self.max_calls:
            self.timestamps.append(now)
            return True
        return False

def parse_data_with_retry(lines, limiter, max_attempts=5):
    parsed = []
    for line in lines:
        attempts = 0
        while attempts < max_attempts:
            if not limiter.allow():
                time.sleep(0.1)
                attempts += 1
                continue
            try:
                parsed.append(float(line.strip()))
                break
            except ValueError:
                parsed.append(None)
                break
    return parsed

if __name__ == "__main__":
    random.seed(42)
    raw_data = [random.randint(0, 100) for _ in range(10)]
    data_lines = [str(x) for x in raw_data] + ["not_a_number"]
    limiter = RateLimiter(max_calls=3, per_seconds=1)
    result = parse_data_with_retry(data_lines, limiter)
    print("Parsed data:", result)

Output

stdout
Parsed data: [26, 39, 32, 52, 86, 56, 55, 55, 7, 32, None]

How it works

The RateLimiter class tracks timestamps of recent calls and prunes entries older than per_seconds. The allow() method checks if the call count is below max_calls before permitting a request. If the limiter blocks, the retry loop sleeps briefly and increments the attempt counter. The parse function gracefully handles invalid input by appending None instead of crashing.

Common mistakes

  • Forgetting to prune old timestamps, causing calls to be blocked indefinitely
  • Not resetting the attempt counter per line, leading to premature exhaustion
  • Sleeping too long on retries, making the script unnecessarily slow

Variations

  1. Use a sliding window with a deque for O(1) pruning
  2. Implement a token bucket algorithm for bursty but bounded traffic

Real-world use cases

  • Throttling outgoing requests to a third-party API to stay within free-tier rate limits.
  • Parsing large datasets from a shared data source without overwhelming the server.
  • Building a web scraper that politely respects site access policies.

Sponsored

Run this sample

Open the browser IDE to tweak the example and see results without installing anything.

Open editor

More from Reliability & rate limiting

Related tutorials and quizzes for this topic.