Skip to main content

Lightweight, thread-safe rate limiting for Python — token bucket, sliding window, fixed window, leaky bucket

Project description

fluxcontrol
Lightweight, thread-safe rate limiting for Python

Version Python 3.10+ License Zero Dependencies Coverage

Zero dependencies. Four algorithms. One API.


Why fluxcontrol?

Rate limiting is a fundamental building block of distributed systems — yet the Python ecosystem forces developers to choose between bloated frameworks and single-algorithm libraries.

  • slowapi bundles Flask/Starlette dependencies and only implements fixed-window counters.
  • ratelimit provides a single decorator with one algorithm and no per-key support.
  • limits (the library behind flask-limiter) is well-designed but pulls in storage backend dependencies and is tightly coupled to web frameworks.
  • flask-limiter only works with Flask and delegates to limits.

fluxcontrol fills a gap that no existing package addresses: a single, dependency-free library that provides four production-proven rate-limiting algorithms through a unified API — usable as a decorator, context manager, or manual guard, without any framework lock-in.

Quick Start

pip install fluxcontrol
from fluxcontrol import RateLimiter

# Decorator
@RateLimiter(calls=10, period=60)
def api_call():
    return do_work()

# Manual check
limiter = RateLimiter(calls=100, period=60)
if limiter.allow("user_123"):
    process_request()

# Context manager
with limiter.acquire("user_123", timeout=5):
    call_external_api()

Use Cases

Use Case Recommended Algorithm Why
API Rate Limiting Token Bucket Allows legitimate bursts while enforcing sustained rate
DDoS Protection Sliding Window Precise control with no boundary-exploitable windows
Resource Throttling Leaky Bucket Smooths output to a fixed rate, prevents resource spikes
Queue Management Leaky Bucket Models queue drain rate naturally
Per-User Limits Any (with key_func) key_func routes each user to an independent bucket
Billing Enforcement Sliding Window Accurate accounting across window boundaries
Simple Capping Fixed Window Minimal overhead when precision isn't critical

Algorithm Comparison

Choosing the right algorithm depends on your traffic pattern and precision requirements:

Token Bucket

The workhorse of rate limiting. Tokens are added at a fixed rate and consumed per request. Accumulated tokens allow bursts up to the bucket capacity, then requests are rejected until tokens refill.

When to use: APIs with variable traffic, user-facing services that need burst tolerance, any scenario where you want to be "generous but bounded."

Sliding Window

Tracks request timestamps in a rolling window. Unlike fixed windows, there are no boundary artifacts — a window starting at 12:59 and one at 13:00 are part of the same continuous time span.

When to use: Billing or quota enforcement where precision matters, compliance-sensitive rate limits, preventing window-boundary attacks.

Fixed Window

Divides time into discrete buckets (e.g., 60-second windows starting at :00 seconds). Counts requests per bucket. Simple, fast, but susceptible to boundary bursts — two requests at 12:59:59 and 13:00:01 each land in different windows.

When to use: Prototyping, internal services where approximate limits suffice, high-throughput scenarios where minimal overhead is critical.

Leaky Bucket

Models a queue with a fixed drain rate. Requests enter a queue; the queue drains at a constant rate regardless of inflow. This smooths traffic rather than rejecting bursts.

When to use: Output to external APIs with strict rate limits, database write throttling, any downstream system that can't handle bursty input.

           Token Bucket              Leaky Bucket
          ┌──────────┐              ┌──────────┐
 Tokens   │ ▓▓▓▓░░░░ │  Requests   │ ▓▓▓░░░░░ │  Queue
 refill → │          │  ──────────→ │          │ ──→ drain
 at rate  │ capacity │             │ capacity │  at rate
          └──────────┘              └──────────┘
          Allows bursts             Smooths output

Features

  • 🧵 Thread-safe by default — all algorithms use internal locking
  • 🔑 Per-key limiting — per user, IP, API key, or any custom key function
  • 🎯 Three usage modes — decorator, context manager, manual guard
  • 📊 Stats & monitoring — built-in usage statistics per key
  • ⏱️ Retry-After — standard HTTP Retry-After header values out of the box
  • 🚫 Zero dependencies — pure Python, no framework coupling
  • 📦 Four algorithms — token bucket, sliding window, fixed window, leaky bucket

Comparison with Existing Solutions

Feature fluxcontrol slowapi ratelimit limits flask-limiter
Token Bucket
Sliding Window
Fixed Window
Leaky Bucket
Zero Dependencies
Per-Key Limiting
Context Manager
Built-in Stats
Framework Agnostic
Thread-Safe

Design Philosophy

  1. Unified API, Multiple Strategies — one RateLimiter class, four algorithms. Switch strategies by changing a string argument — no rewrites, no adapter pattern ceremony.

  2. Zero-Dependency by Default — no Redis, no Flask, no Celery. Import and go. Add storage backends only when you need distributed coordination.

  3. Framework Agnostic — fluxcontrol doesn't know or care whether you're building a Flask API, a FastAPI service, a CLI tool, or a background worker. Rate limiting is orthogonal to your framework choice.

  4. Safety First — every public method is thread-safe. No footguns. RateLimitExceeded exceptions carry retry_after values so you can build compliant HTTP responses without extra math.

  5. Progressive Complexity — start with @RateLimiter(calls=100, period=60). Add per-key limiting. Switch algorithms. Plug in custom key functions. Each layer of complexity is opt-in.

API Reference

RateLimiter(calls, period, algorithm="token_bucket", ...)

High-level API supporting all four algorithms.

RateLimiter(
    calls=100,           # max calls per period
    period=60,           # time window in seconds
    algorithm="token_bucket",  # "token_bucket", "sliding_window", "fixed_window", "leaky_bucket"
    key_func=lambda user: user,  # per-key rate limiting
    burst=150,           # burst capacity (token bucket)
    raise_on_limit=True, # raise exception or return None
)

Low-Level APIs

from fluxcontrol import TokenBucket, SlidingWindow, FixedWindow, LeakyBucket

# Token Bucket — allows bursts up to capacity
tb = TokenBucket(rate=10, capacity=50)
tb.allow()          # consume 1 token
tb.consume(5)       # consume 5 tokens
tb.retry_after()    # seconds until next available
tb.available        # current token count
tb.stats()          # usage statistics

# Sliding Window — precise, no boundary burst
sw = SlidingWindow(max_calls=100, window_seconds=60)
sw.allow("user_id")
sw.count            # calls in current window
sw.retry_after("user_id")

# Fixed Window — simple, fast
fw = FixedWindow(max_calls=100, window_seconds=60)
fw.allow("user_id")

# Leaky Bucket — smooth output rate
lb = LeakyBucket(rate=10, capacity=50)
lb.allow("user_id")
lb.level            # current queue level

Exceptions

from fluxcontrol.exceptions import RateLimitExceeded, TimeoutExceeded

try:
    rate_limited_func()
except RateLimitExceeded as e:
    retry_after = e.retry_after  # seconds to wait

License

MIT © Ravi Teja Prabhala Venkata

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

fluxrate-0.3.0.tar.gz (15.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

fluxrate-0.3.0-py3-none-any.whl (12.7 kB view details)

Uploaded Python 3

File details

Details for the file fluxrate-0.3.0.tar.gz.

File metadata

  • Download URL: fluxrate-0.3.0.tar.gz
  • Upload date:
  • Size: 15.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.5

File hashes

Hashes for fluxrate-0.3.0.tar.gz
Algorithm Hash digest
SHA256 7036ada091eb1dce6ded3c0b45557918e53b62521355c0e973dd598df37acd77
MD5 8fcd67ff18e6013904a87d98766f7a62
BLAKE2b-256 eb6a379826f175e2e1c38ac1db54d02f3ec0ee98b00bb6307d1f583c81f3ae44

See more details on using hashes here.

File details

Details for the file fluxrate-0.3.0-py3-none-any.whl.

File metadata

  • Download URL: fluxrate-0.3.0-py3-none-any.whl
  • Upload date:
  • Size: 12.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.5

File hashes

Hashes for fluxrate-0.3.0-py3-none-any.whl
Algorithm Hash digest
SHA256 a894f04c6aa2d8eb5c3f16435c213e76475d31cf7f7da5a816847ce294d36220
MD5 3f7b85fc4a2f27d610c89355ee7993ad
BLAKE2b-256 c74411af5b0ed055a3246c84385d148b873c8333d5f1b4a73cfb4c325dff6e04

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page