# API Reference

`limits` | Rate limiting with commonly used storage backends
`limits.strategies` | Rate limiting strategies
`limits.storage` | Implementations of storage backends to be used with `limits.strategies.RateLimiter` strategies
`limits.aio.strategies` | Asynchronous rate limiting strategies
`limits.aio.storage` | Implementations of storage backends to be used with `limits.aio.strategies.RateLimiter` strategies

## Strategies

### Synchronous Strategies

The available built in rate limiting strategies which expect a single parameter: a subclass of `Storage`.

Provided by `limits.strategies`

class FixedWindowRateLimiter(storage: StorageTypes)

  Reference: Fixed Window

  hit(item: RateLimitItem, *identifiers: str, cost: int = 1) → bool

    Consume the rate limit

    Parameters:

      - item – The rate limit item

      - identifiers – variable list of strings to uniquely identify this instance of the limit

      - cost – The cost of this hit, default 1

  test(item: RateLimitItem, *identifiers: str, cost: int = 1) → bool

    Check if the rate limit can be consumed

    Parameters:

      - item – The rate limit item

      - identifiers – variable list of strings to uniquely identify this instance of the limit

      - cost – The expected cost to be consumed, default 1

  get_window_stats(item: RateLimitItem, *identifiers: str) → WindowStats

    Query the reset time and remaining amount for the limit

    Parameters:

      - item – The rate limit item

      - identifiers – variable list of strings to uniquely identify this instance of the limit

    Returns:

      (reset time, remaining)

class FixedWindowElasticExpiryRateLimiter(*args, **kwargs)

  Reference: Fixed Window with Elastic Expiry

  Deprecated since version 4.1.

  hit(item: RateLimitItem, *identifiers: str, cost: int = 1) → bool

    Consume the rate limit

    Parameters:

      - item – The rate limit item

      - identifiers – variable list of strings to uniquely identify this instance of the limit

      - cost – The cost of this hit, default 1

  get_window_stats(item: RateLimitItem, *identifiers: str) → WindowStats

    Query the reset time and remaining amount for the limit

    Parameters:

      - item – The rate limit item

      - identifiers – variable list of strings to uniquely identify this instance of the limit

    Returns:

      (reset time, remaining)

  test(item: RateLimitItem, *identifiers: str, cost: int = 1) → bool

    Check if the rate limit can be consumed

    Parameters:

      - item – The rate limit item

      - identifiers – variable list of strings to uniquely identify this instance of the limit

      - cost – The expected cost to be consumed, default 1

class MovingWindowRateLimiter(storage: StorageTypes)

  Reference: Moving Window

  hit(item: RateLimitItem, *identifiers: str, cost: int = 1) → bool

    Consume the rate limit

    Parameters:

      - item – The rate limit item

      - identifiers – variable list of strings to uniquely identify this instance of the limit

      - cost – The cost of this hit, default 1

    Returns:

      (reset time, remaining)

  test(item: RateLimitItem, *identifiers: str, cost: int = 1) → bool

    Check if the rate limit can be consumed

    Parameters:

      - item – The rate limit item

      - identifiers – variable list of strings to uniquely identify this instance of the limit

      - cost – The expected cost to be consumed, default 1

  get_window_stats(item: RateLimitItem, *identifiers: str) → WindowStats

    returns the number of requests remaining within this limit.

    Parameters:

      - item – The rate limit item

      - identifiers – variable list of strings to uniquely identify this instance of the limit

    Returns:

      tuple (reset time, remaining)

class SlidingWindowCounterRateLimiter(storage: StorageTypes)

  Reference: Sliding Window Counter

  Added in version 4.1.

  hit(item: RateLimitItem, *identifiers: str, cost: int = 1) → bool

    Consume the rate limit

    Parameters:

      - item – The rate limit item

      - identifiers – variable list of strings to uniquely identify this instance of the limit

      - cost – The cost of this hit, default 1

  test(item: RateLimitItem, *identifiers: str, cost: int = 1) → bool

    Check if the rate limit can be consumed

    Parameters:

      - item – The rate limit item

      - identifiers – variable list of strings to uniquely identify this instance of the limit

      - cost – The expected cost to be consumed, default 1

  get_window_stats(item: RateLimitItem, *identifiers: str) → WindowStats

    Query the reset time and remaining amount for the limit.

    Parameters:

      - item – The rate limit item

      - identifiers – variable list of strings to uniquely identify this instance of the limit

    Returns:

      WindowStats(reset time, remaining)

All strategies implement the same abstract base class:

class RateLimiter(storage: StorageTypes)
  abstractmethod hit(item: RateLimitItem, *identifiers: str, cost: int = 1) → bool

    Consume the rate limit

    Parameters:

      - item – The rate limit item

      - identifiers – variable list of strings to uniquely identify this instance of the limit

      - cost – The cost of this hit, default 1

  abstractmethod test(item: RateLimitItem, *identifiers: str, cost: int = 1) → bool

    Check the rate limit without consuming from it.

    Parameters:

      - item – The rate limit item

      - identifiers – variable list of strings to uniquely identify this instance of the limit

      - cost – The expected cost to be consumed, default 1

  abstractmethod get_window_stats(item: RateLimitItem, *identifiers: str) → WindowStats

    Query the reset time and remaining amount for the limit

    Parameters:

      - item – The rate limit item

      - identifiers – variable list of strings to uniquely identify this instance of the limit

    Returns:

      (reset time, remaining)

### Async Strategies

These variants should be used in for asyncio support. These strategies expose async variants and expect a subclass of `limits.aio.storage.Storage`

Provided by `limits.aio.strategies`

class FixedWindowRateLimiter(storage: StorageTypes)

  Reference: Fixed Window

  async hit(item: RateLimitItem, *identifiers: str, cost: int = 1) → bool

    Consume the rate limit

    Parameters:

      - item – the rate limit item

      - identifiers – variable list of strings to uniquely identify the limit

      - cost – The cost of this hit, default 1

  async test(item: RateLimitItem, *identifiers: str, cost: int = 1) → bool

    Check if the rate limit can be consumed

    Parameters:

      - item – the rate limit item

      - identifiers – variable list of strings to uniquely identify the limit

      - cost – The expected cost to be consumed, default 1

  async get_window_stats(item: RateLimitItem, *identifiers: str) → WindowStats

    Query the reset time and remaining amount for the limit

    Parameters:

      - item – the rate limit item

      - identifiers – variable list of strings to uniquely identify the limit

    Returns:

      reset time, remaining

class FixedWindowElasticExpiryRateLimiter(*args, **kwargs)

  Reference: Fixed Window with Elastic Expiry

  Deprecated since version 4.1.

  async hit(item: RateLimitItem, *identifiers: str, cost: int = 1) → bool

    Consume the rate limit

    Parameters:

      - item – a `limits.limits.RateLimitItem` instance

      - identifiers – variable list of strings to uniquely identify the limit

      - cost – The cost of this hit, default 1

  async get_window_stats(item: RateLimitItem, *identifiers: str) → WindowStats

    Query the reset time and remaining amount for the limit

    Parameters:

      - item – the rate limit item

      - identifiers – variable list of strings to uniquely identify the limit

    Returns:

      reset time, remaining

  async test(item: RateLimitItem, *identifiers: str, cost: int = 1) → bool

    Check if the rate limit can be consumed

    Parameters:

      - item – the rate limit item

      - identifiers – variable list of strings to uniquely identify the limit

      - cost – The expected cost to be consumed, default 1

class MovingWindowRateLimiter(storage: StorageTypes)

  Reference: Moving Window

  async hit(item: RateLimitItem, *identifiers: str, cost: int = 1) → bool

    Consume the rate limit

    Parameters:

      - item – the rate limit item

      - identifiers – variable list of strings to uniquely identify the limit

      - cost – The cost of this hit, default 1

  async test(item: RateLimitItem, *identifiers: str, cost: int = 1) → bool

    Check if the rate limit can be consumed

    Parameters:

      - item – the rate limit item

      - identifiers – variable list of strings to uniquely identify the limit

      - cost – The expected cost to be consumed, default 1

  async get_window_stats(item: RateLimitItem, *identifiers: str) → WindowStats

    returns the number of requests remaining within this limit.

    Parameters:

      - item – the rate limit item

      - identifiers – variable list of strings to uniquely identify the limit

    Returns:

      (reset time, remaining)

class SlidingWindowCounterRateLimiter(storage: StorageTypes)

  Reference: Sliding Window Counter

  Added in version 4.1.

  async hit(item: RateLimitItem, *identifiers: str, cost: int = 1) → bool

    Consume the rate limit

    Parameters:

      - item – The rate limit item

      - identifiers – variable list of strings to uniquely identify this instance of the limit

      - cost – The cost of this hit, default 1

  async test(item: RateLimitItem, *identifiers: str, cost: int = 1) → bool

    Check if the rate limit can be consumed

    Parameters:

      - item – The rate limit item

      - identifiers – variable list of strings to uniquely identify this instance of the limit

      - cost – The expected cost to be consumed, default 1

  async get_window_stats(item: RateLimitItem, *identifiers: str) → WindowStats

    Query the reset time and remaining amount for the limit.

    Parameters:

      - item – The rate limit item

      - identifiers – variable list of strings to uniquely identify this instance of the limit

    Returns:

      (reset time, remaining)

All strategies implement the same abstract base class:

class RateLimiter(storage: StorageTypes)
  abstractmethod async hit(item: RateLimitItem, *identifiers: str, cost: int = 1) → bool

    Consume the rate limit

    Parameters:

      - item – the rate limit item

      - identifiers – variable list of strings to uniquely identify the limit

      - cost – The cost of this hit, default 1

  abstractmethod async test(item: RateLimitItem, *identifiers: str, cost: int = 1) → bool

    Check if the rate limit can be consumed

    Parameters:

      - item – the rate limit item

      - identifiers – variable list of strings to uniquely identify the limit

      - cost – The expected cost to be consumed, default 1

  abstractmethod async get_window_stats(item: RateLimitItem, *identifiers: str) → WindowStats

    Query the reset time and remaining amount for the limit

    Parameters:

      - item – the rate limit item

      - identifiers – variable list of strings to uniquely identify the limit

    Returns:

      (reset time, remaining))

## Storage

### Storage Factory function

Provided by `limits.storage`

storage_from_string(storage_string: str, **options: float | str | bool) → Storage | Storage

  Factory function to get an instance of the storage class based on the uri of the storage. In most cases using it should be sufficient instead of directly instantiating the storage classes. for example:

      from limits.storage import storage_from_string

      memory = storage_from_string("memory://")
      memcached = storage_from_string("memcached://localhost:11211")
      redis = storage_from_string("redis://localhost:6379")

  The same function can be used to construct the Async Storage variants, for example:

      from limits.storage import storage_from_string

      memory = storage_from_string("async+memory://")
      memcached = storage_from_string("async+memcached://localhost:11211")
      redis = storage_from_string("async+redis://localhost:6379")

  Parameters:

    - storage_string – a string of the form `scheme://host:port`. More details about supported storage schemes can be found at Storage scheme

    - options – all remaining keyword arguments are passed to the constructor matched by `storage_string`.

  Raises:

    ConfigurationError – when the `storage_string` cannot be mapped to a registered `limits.storage.Storage` or `limits.aio.storage.Storage` instance.

### Synchronous Storage

Provided by `limits.storage`

#### In-Memory Storage

class MemoryStorage(uri: str | None = None, wrap_exceptions: bool = False, **_: str)

  rate limit storage using `collections.Counter` as an in memory storage for fixed and elastic window strategies, and a simple list to implement moving window strategy.

  Parameters:

    wrap_exceptions – Whether to wrap storage exceptions in `limits.errors.StorageError` before raising it.

  STORAGE_SCHEME: list[str] | None = ['memory']

    The storage schemes to register against this implementation

  incr(key: str, expiry: float, elastic_expiry: bool = False, amount: int = 1) → int

    increments the counter for a given rate limit key

    Parameters:

      - key – the key to increment

      - expiry – amount in seconds for the key to expire in

      - elastic_expiry – whether to keep extending the rate limit window every hit.

      - amount – the number to increment by

  decr(key: str, amount: int = 1) → int

    decrements the counter for a given rate limit key

    Parameters:

      - key – the key to decrement

      - amount – the number to decrement by

  get(key: str) → int
    Parameters:

      key – the key to get the counter value for

  clear(key: str) → None
    Parameters:

      key – the key to clear rate limits for

  acquire_entry(key: str, limit: int, expiry: int, amount: int = 1) → bool
    Parameters:

      - key – rate limit key to acquire an entry in

      - limit – amount of entries allowed

      - expiry – expiry of the entry

      - amount – the number of entries to acquire

  get_expiry(key: str) → float
    Parameters:

      key – the key to get the expiry for

  get_num_acquired(key: str, expiry: int) → int

    returns the number of entries already acquired

    Parameters:

      - key – rate limit key to acquire an entry in

      - expiry – expiry of the entry

  get_moving_window(key: str, limit: int, expiry: int) → tuple[float, int]

    returns the starting point and the number of entries in the moving window

    Parameters:

      - key – rate limit key

      - expiry – expiry of entry

    Returns:

      (start of window, number of acquired entries)

  acquire_sliding_window_entry(key: str, limit: int, expiry: int, amount: int = 1) → bool

    Acquire an entry if the weighted count of the current and previous windows is less than or equal to the limit

    Parameters:

      - key – rate limit key to acquire an entry in

      - limit – amount of entries allowed

      - expiry – expiry of the entry

      - amount – the number of entries to acquire

  get_sliding_window(key: str, expiry: int) → tuple[int, float, int, float]

    Return the previous and current window information.

    Parameters:

      - key – the rate limit key

      - expiry – the rate limit expiry, needed to compute the key in some implementations

    Returns:

      a tuple of (int, float, int, float) with the following information: - previous window counter - previous window TTL - current window counter - current window TTL

  check() → bool

    check if storage is healthy

  reset() → int | None

    reset storage to clear limits

  DEPENDENCIES: dict[str, Version | None] | list[str] = []

    The python modules this class has a dependency on. Used to lazily populate the `dependencies`

  classmethod sliding_window_keys(key: str, expiry: int, at: float) → tuple[str, str]

    returns the previous and the current window’s keys.

    Parameters:

      - key – the key to get the window’s keys from

      - expiry – the expiry of the limit item, in seconds

      - at – the timestamp to get the keys from. Default to now, ie `time.time()`

    Returns a tuple with the previous and the current key: (previous, current).

    Example:

      - key = “mykey”

      - expiry = 60

      - at = 1738576292.6631825

    The return value will be the tuple `("mykey/28976271", "mykey/28976270")`.

#### Redis Storage

class RedisStorage(uri: str, connection_pool: redis.connection.ConnectionPool | None = None, wrap_exceptions: bool = False, **options: float | str | bool)

  Rate limit storage with redis as backend.

  Depends on redis (or valkey if `uri` starts with `valkey://`)

  Changed in version 4.3: Added support for using the redis client from valkey if `uri` has the `valkey://` schema

  Parameters:

    - uri –

      uri of the form `redis://[:password]@host:port`, `redis://[:password]@host:port/db`, `rediss://[:password]@host:port`, `redis+unix:///path/to/sock` etc. This uri is passed directly to `redis.from_url()` except for the case of `redis+unix://` where it is replaced with `unix://`.

      If the uri scheme is `valkey` the implementation used will be from valkey.

    - connection_pool – if provided, the redis client is initialized with the connection pool and any other params passed as `options`

    - wrap_exceptions – Whether to wrap storage exceptions in `limits.errors.StorageError` before raising it.

    - options – all remaining keyword arguments are passed directly to the constructor of `redis.Redis`

  Raises:

    ConfigurationError – when the redis library is not available

  STORAGE_SCHEME: list[str] | None = ['redis', 'rediss', 'redis+unix', 'valkey', 'valkeys', 'valkey+unix']

    The storage scheme for redis

  DEPENDENCIES: dict[str, Version | None] | list[str] = {'redis': <Version('3.0')>, 'valkey': <Version('6.0')>}

    The python modules this class has a dependency on. Used to lazily populate the `dependencies`

  get_moving_window(key: str, limit: int, expiry: int) → tuple[float, int]

    returns the starting point and the number of entries in the moving window

    Parameters:

      - key – rate limit key

      - expiry – expiry of entry

    Returns:

      (start of window, number of acquired entries)

  get_sliding_window(key: str, expiry: int) → tuple[int, float, int, float]

    Return the previous and current window information.

    Parameters:

      - key – the rate limit key

      - expiry – the rate limit expiry, needed to compute the key in some implementations

    Returns:

      a tuple of (int, float, int, float) with the following information: - previous window counter - previous window TTL - current window counter - current window TTL

  incr(key: str, expiry: int, elastic_expiry: bool = False, amount: int = 1) → int

    increments the counter for a given rate limit key

    Parameters:

      - key – the key to increment

      - expiry – amount in seconds for the key to expire in

      - amount – the number to increment by

  get(key: str) → int
    Parameters:

      key – the key to get the counter value for

  clear(key: str) → None
    Parameters:

      key – the key to clear rate limits for

  acquire_entry(key: str, limit: int, expiry: int, amount: int = 1) → bool
    Parameters:

      - key – rate limit key to acquire an entry in

      - limit – amount of entries allowed

      - expiry – expiry of the entry

      - amount – the number of entries to acquire

  acquire_sliding_window_entry(key: str, limit: int, expiry: int, amount: int = 1) → bool

    Acquire an entry. Shift the current window to the previous window if it expired.

    Parameters:

      - key – rate limit key to acquire an entry in

      - limit – amount of entries allowed

      - expiry – expiry of the entry

      - amount – the number of entries to acquire

  get_expiry(key: str) → float
    Parameters:

      key – the key to get the expiry for

  check() → bool

    check if storage is healthy

  reset() → int | None

    This function calls a Lua Script to delete keys prefixed with `self.PREFIX` in blocks of 5000.

    Warning

    This operation was designed to be fast, but was not tested on a large production based system. Be careful with its usage as it could be slow on very large data sets.

#### Redis Cluster Storage

class RedisClusterStorage(uri: str, wrap_exceptions: bool = False, **options: float | str | bool)

  Rate limit storage with redis cluster as backend

  Depends on redis (or valkey if `uri` starts with `valkey+cluster://`).

  Changed in version 4.3: Added support for using the redis client from valkey if `uri` has the `valkey+cluster://` schema

  Changed in version 2.5.0: Cluster support was provided by the redis-py-cluster library which has been absorbed into the official redis client. By default the `redis.cluster.RedisCluster` client will be used however if the version of the package is lower than `4.2.0` the implementation will fallback to trying to use `rediscluster.RedisCluster`.

  Changed in version 3.14.0: Dropped support for the redis-py-cluster library which has been abandoned/deprecated.

  Parameters:

    - uri –

      url of the form `redis+cluster://[:password]@host:port,host:port`

      If the uri scheme is `valkey+cluster` the implementation used will be from valkey.

    - wrap_exceptions – Whether to wrap storage exceptions in `limits.errors.StorageError` before raising it.

    - options – all remaining keyword arguments are passed directly to the constructor of `redis.cluster.RedisCluster`

  Raises:

    ConfigurationError – when the redis library is not available or if the redis cluster cannot be reached.

  STORAGE_SCHEME: list[str] | None = ['redis+cluster', 'valkey+cluster']

    The storage scheme for redis cluster

  DEFAULT_OPTIONS: dict[str, float | str | bool] = {'max_connections': 1000}

    Default options passed to the `RedisCluster`

  DEPENDENCIES: dict[str, Version | None] | list[str] = {'redis': <Version('4.2.0')>, 'valkey': <Version('6.0')>}

    The python modules this class has a dependency on. Used to lazily populate the `dependencies`

  acquire_entry(key: str, limit: int, expiry: int, amount: int = 1) → bool
    Parameters:

      - key – rate limit key to acquire an entry in

      - limit – amount of entries allowed

      - expiry – expiry of the entry

      - amount – the number of entries to acquire

  acquire_sliding_window_entry(key: str, limit: int, expiry: int, amount: int = 1) → bool

    Acquire an entry. Shift the current window to the previous window if it expired.

    Parameters:

      - key – rate limit key to acquire an entry in

      - limit – amount of entries allowed

      - expiry – expiry of the entry

      - amount – the number of entries to acquire

  check() → bool

    check if storage is healthy

  clear(key: str) → None
    Parameters:

      key – the key to clear rate limits for

  get(key: str) → int
    Parameters:

      key – the key to get the counter value for

  get_expiry(key: str) → float
    Parameters:

      key – the key to get the expiry for

  get_moving_window(key: str, limit: int, expiry: int) → tuple[float, int]

    returns the starting point and the number of entries in the moving window

    Parameters:

      - key – rate limit key

      - expiry – expiry of entry

    Returns:

      (start of window, number of acquired entries)

  get_sliding_window(key: str, expiry: int) → tuple[int, float, int, float]

    Return the previous and current window information.

    Parameters:

      - key – the rate limit key

      - expiry – the rate limit expiry, needed to compute the key in some implementations

    Returns:

      a tuple of (int, float, int, float) with the following information: - previous window counter - previous window TTL - current window counter - current window TTL

  incr(key: str, expiry: int, elastic_expiry: bool = False, amount: int = 1) → int

    increments the counter for a given rate limit key

    Parameters:

      - key – the key to increment

      - expiry – amount in seconds for the key to expire in

      - amount – the number to increment by

  reset() → int | None

    Redis Clusters are sharded and deleting across shards can’t be done atomically. Because of this, this reset loops over all keys that are prefixed with `self.PREFIX` and calls delete on them, one at a time.

    Warning

    This operation was not tested with extremely large data sets. On a large production based system, care should be taken with its usage as it could be slow on very large data sets

#### Redis Sentinel Storage

class RedisSentinelStorage(uri: str, service_name: str | None = None, use_replicas: bool = True, sentinel_kwargs: dict[str, float | str | bool] | None = None, wrap_exceptions: bool = False, **options: float | str | bool)

  Rate limit storage with redis sentinel as backend

  Depends on redis package (or valkey if `uri` starts with `valkey+sentinel://`)

  Changed in version 4.3: Added support for using the redis client from valkey if `uri` has the `valkey+sentinel://` schema

  Parameters:

    - uri –

      url of the form `redis+sentinel://host:port,host:port/service_name`

      If the uri scheme is `valkey+sentinel` the implementation used will be from valkey.

    - service_name – sentinel service name (if not provided in `uri`)

    - use_replicas – Whether to use replicas for read only operations

    - sentinel_kwargs – kwargs to pass as `sentinel_kwargs` to `redis.sentinel.Sentinel`

    - wrap_exceptions – Whether to wrap storage exceptions in `limits.errors.StorageError` before raising it.

    - options – all remaining keyword arguments are passed directly to the constructor of `redis.sentinel.Sentinel`

  Raises:

    ConfigurationError – when the redis library is not available or if the redis master host cannot be pinged.

  STORAGE_SCHEME: list[str] | None = ['redis+sentinel', 'valkey+sentinel']

    The storage scheme for redis accessed via a redis sentinel installation

  DEPENDENCIES: dict[str, Version | None] | list[str] = {'redis': <Version('3.0')>, 'redis.sentinel': <Version('3.0')>, 'valkey': <Version('6.0')>, 'valkey.sentinel': <Version('6.0')>}

    The python modules this class has a dependency on. Used to lazily populate the `dependencies`

  acquire_entry(key: str, limit: int, expiry: int, amount: int = 1) → bool
    Parameters:

      - key – rate limit key to acquire an entry in

      - limit – amount of entries allowed

      - expiry – expiry of the entry

      - amount – the number of entries to acquire

  acquire_sliding_window_entry(key: str, limit: int, expiry: int, amount: int = 1) → bool

    Acquire an entry. Shift the current window to the previous window if it expired.

    Parameters:

      - key – rate limit key to acquire an entry in

      - limit – amount of entries allowed

      - expiry – expiry of the entry

      - amount – the number of entries to acquire

  check() → bool

    check if storage is healthy

  clear(key: str) → None
    Parameters:

      key – the key to clear rate limits for

  get(key: str) → int
    Parameters:

      key – the key to get the counter value for

  get_expiry(key: str) → float
    Parameters:

      key – the key to get the expiry for

  get_moving_window(key: str, limit: int, expiry: int) → tuple[float, int]

    returns the starting point and the number of entries in the moving window

    Parameters:

      - key – rate limit key

      - expiry – expiry of entry

    Returns:

      (start of window, number of acquired entries)

  get_sliding_window(key: str, expiry: int) → tuple[int, float, int, float]

    Return the previous and current window information.

    Parameters:

      - key – the rate limit key

      - expiry – the rate limit expiry, needed to compute the key in some implementations

    Returns:

      a tuple of (int, float, int, float) with the following information: - previous window counter - previous window TTL - current window counter - current window TTL

  incr(key: str, expiry: int, elastic_expiry: bool = False, amount: int = 1) → int

    increments the counter for a given rate limit key

    Parameters:

      - key – the key to increment

      - expiry – amount in seconds for the key to expire in

      - amount – the number to increment by

  reset() → int | None

    This function calls a Lua Script to delete keys prefixed with `self.PREFIX` in blocks of 5000.

    Warning

    This operation was designed to be fast, but was not tested on a large production based system. Be careful with its usage as it could be slow on very large data sets.

#### Memcached Storage

class MemcachedStorage(uri: str, wrap_exceptions: bool = False, **options: str | Callable[[], MemcachedClientP])

  Rate limit storage with memcached as backend.

  Depends on pymemcache.

  Parameters:

    - uri – memcached location of the form `memcached://host:port,host:port`, `memcached:///var/tmp/path/to/sock`

    - wrap_exceptions – Whether to wrap storage exceptions in `limits.errors.StorageError` before raising it.

    - options – all remaining keyword arguments are passed directly to the constructor of `pymemcache.client.base.PooledClient` or `pymemcache.client.hash.HashClient` (if there are more than one hosts specified)

  Raises:

    ConfigurationError – when pymemcache is not available

  STORAGE_SCHEME: list[str] | None = ['memcached']

    The storage scheme for memcached

  DEPENDENCIES: dict[str, Version | None] | list[str] = ['pymemcache']

    The python modules this class has a dependency on. Used to lazily populate the `dependencies`

  get_client(module: ModuleType, hosts: list[tuple[str, int]], **kwargs: str) → MemcachedClientP

    returns a memcached client.

    Parameters:

      - module – the memcached module

      - hosts – list of memcached hosts

  property storage: MemcachedClientP

    lazily creates a memcached client instance using a thread local

  get(key: str) → int
    Parameters:

      key – the key to get the counter value for

  get_many(keys: Iterable[str]) → dict[str, Any]

    Return multiple counters at once

    Parameters:

      keys – the keys to get the counter values for

  clear(key: str) → None
    Parameters:

      key – the key to clear rate limits for

  incr(key: str, expiry: float, elastic_expiry: bool = False, amount: int = 1, set_expiration_key: bool = True) → int

    increments the counter for a given rate limit key

    Parameters:

      - key – the key to increment

      - expiry – amount in seconds for the key to expire in

      - elastic_expiry – whether to keep extending the rate limit window every hit.

      - amount – the number to increment by

      - set_expiration_key – set the expiration key with the expiration time if needed. If set to False, the key will still expire, but memcached cannot provide the expiration time.

  get_expiry(key: str) → float
    Parameters:

      key – the key to get the expiry for

  check() → bool

    Check if storage is healthy by calling the `get` command on the key `limiter-check`

  reset() → int | None

    reset storage to clear limits

  acquire_sliding_window_entry(key: str, limit: int, expiry: int, amount: int = 1) → bool

    Acquire an entry if the weighted count of the current and previous windows is less than or equal to the limit

    Parameters:

      - key – rate limit key to acquire an entry in

      - limit – amount of entries allowed

      - expiry – expiry of the entry

      - amount – the number of entries to acquire

  get_sliding_window(key: str, expiry: int) → tuple[int, float, int, float]

    Return the previous and current window information.

    Parameters:

      - key – the rate limit key

      - expiry – the rate limit expiry, needed to compute the key in some implementations

    Returns:

      a tuple of (int, float, int, float) with the following information: - previous window counter - previous window TTL - current window counter - current window TTL

  classmethod sliding_window_keys(key: str, expiry: int, at: float) → tuple[str, str]

    returns the previous and the current window’s keys.

    Parameters:

      - key – the key to get the window’s keys from

      - expiry – the expiry of the limit item, in seconds

      - at – the timestamp to get the keys from. Default to now, ie `time.time()`

    Returns a tuple with the previous and the current key: (previous, current).

    Example:

      - key = “mykey”

      - expiry = 60

      - at = 1738576292.6631825

    The return value will be the tuple `("mykey/28976271", "mykey/28976270")`.

#### MongoDB Storage

class MongoDBStorage(uri: str, database_name: str = 'limits', counter_collection_name: str = 'counters', window_collection_name: str = 'windows', wrap_exceptions: bool = False, **options: int | str | bool)

  Changed in version 3.14.0: Added option to select custom collection names for windows & counters

  Added in version 2.1.

  Parameters:

    - uri – uri of the form `mongodb://[user:password]@host:port?...`, This uri is passed directly to `MongoClient`

    - database_name – The database to use for storing the rate limit collections.

    - counter_collection_name – The collection name to use for individual counters used in fixed window strategies

    - window_collection_name – The collection name to use for sliding & moving window storage

    - wrap_exceptions – Whether to wrap storage exceptions in `limits.errors.StorageError` before raising it.

    - options – all remaining keyword arguments are passed to the constructor of `MongoClient`

  Raises:

    ConfigurationError – when the pymongo library is not available

  STORAGE_SCHEME: list[str] | None = ['mongodb', 'mongodb+srv']

    The storage schemes to register against this implementation

  DEPENDENCIES: dict[str, Version | None] | list[str] = ['pymongo']

    The python modules this class has a dependency on. Used to lazily populate the `dependencies`

  acquire_entry(key: str, limit: int, expiry: int, amount: int = 1) → bool
    Parameters:

      - key – rate limit key to acquire an entry in

      - limit – amount of entries allowed

      - expiry – expiry of the entry

      - amount – the number of entries to acquire

  acquire_sliding_window_entry(key: str, limit: int, expiry: int, amount: int = 1) → bool

    Acquire an entry if the weighted count of the current and previous windows is less than or equal to the limit

    Parameters:

      - key – rate limit key to acquire an entry in

      - limit – amount of entries allowed

      - expiry – expiry of the entry

      - amount – the number of entries to acquire

  check() → bool

    Check if storage is healthy by calling `pymongo.mongo_client.MongoClient.server_info()`

  clear(key: str) → None
    Parameters:

      key – the key to clear rate limits for

  get(key: str) → int
    Parameters:

      key – the key to get the counter value for

  get_expiry(key: str) → float
    Parameters:

      key – the key to get the expiry for

  get_moving_window(key: str, limit: int, expiry: int) → tuple[float, int]

    returns the starting point and the number of entries in the moving window

    Parameters:

      - key – rate limit key

      - expiry – expiry of entry

    Returns:

      (start of window, number of acquired entries)

  get_sliding_window(key: str, expiry: int) → tuple[int, float, int, float]

    Return the previous and current window information.

    Parameters:

      - key – the rate limit key

      - expiry – the rate limit expiry, needed to compute the key in some implementations

    Returns:

      a tuple of (int, float, int, float) with the following information: - previous window counter - previous window TTL - current window counter - current window TTL

  incr(key: str, expiry: int, elastic_expiry: bool = False, amount: int = 1) → int

    increments the counter for a given rate limit key

    Parameters:

      - key – the key to increment

      - expiry – amount in seconds for the key to expire in

      - amount – the number to increment by

  reset() → int | None

    Delete all rate limit keys in the rate limit collections (counters, windows)

#### Etcd Storage

class EtcdStorage(*args, **kwargs)

  Rate limit storage with etcd as backend.

  Depends on etcd3.

  Deprecated since version 4.4.

  Parameters:

    - uri – etcd location of the form `etcd://host:port`,

    - max_retries – Maximum number of attempts to retry in the case of concurrent updates to a rate limit key

    - wrap_exceptions – Whether to wrap storage exceptions in `limits.errors.StorageError` before raising it.

    - options – all remaining keyword arguments are passed directly to the constructor of `etcd3.Etcd3Client`

  Raises:

    ConfigurationError – when etcd3 is not available

  STORAGE_SCHEME: list[str] | None = ['etcd']

    The storage scheme for etcd

  DEPENDENCIES: dict[str, Version | None] | list[str] = ['etcd3']

    The python modules this class has a dependency on. Used to lazily populate the `dependencies`

  incr(key: str, expiry: int, elastic_expiry: bool = False, amount: int = 1) → int

    increments the counter for a given rate limit key

    Parameters:

      - key – the key to increment

      - expiry – amount in seconds for the key to expire in

      - elastic_expiry – whether to keep extending the rate limit window every hit.

      - amount – the number to increment by

  get(key: str) → int
    Parameters:

      key – the key to get the counter value for

  get_expiry(key: str) → float
    Parameters:

      key – the key to get the expiry for

  check() → bool

    check if storage is healthy

  reset() → int | None

    reset storage to clear limits

  clear(key: str) → None

    resets the rate limit key

    Parameters:

      key – the key to clear rate limits for

### Async Storage

Provided by `limits.aio.storage`

#### Async In-Memory Storage

class MemoryStorage(uri: str | None = None, wrap_exceptions: bool = False, **_: str)

  rate limit storage using `collections.Counter` as an in memory storage for fixed and elastic window strategies, and a simple list to implement moving window strategy.

  Added in version 2.1.

  Parameters:

    wrap_exceptions – Whether to wrap storage exceptions in `limits.errors.StorageError` before raising it.

  STORAGE_SCHEME: list[str] | None = ['async+memory']

    The storage scheme for in process memory storage for use in an async context

  async incr(key: str, expiry: float, elastic_expiry: bool = False, amount: int = 1) → int

    increments the counter for a given rate limit key

    Parameters:

      - key – the key to increment

      - expiry – amount in seconds for the key to expire in

      - elastic_expiry – whether to keep extending the rate limit window every hit.

      - amount – the number to increment by

  async decr(key: str, amount: int = 1) → int

    decrements the counter for a given rate limit key. 0 is the minimum allowed value.

    Parameters:

      amount – the number to increment by

  async get(key: str) → int
    Parameters:

      key – the key to get the counter value for

  async clear(key: str) → None
    Parameters:

      key – the key to clear rate limits for

  async acquire_entry(key: str, limit: int, expiry: int, amount: int = 1) → bool
    Parameters:

      - key – rate limit key to acquire an entry in

      - limit – amount of entries allowed

      - expiry – expiry of the entry

      - amount – the number of entries to acquire

  async get_expiry(key: str) → float
    Parameters:

      key – the key to get the expiry for

  async get_num_acquired(key: str, expiry: int) → int

    returns the number of entries already acquired

    Parameters:

      - key – rate limit key to acquire an entry in

      - expiry – expiry of the entry

  async get_moving_window(key: str, limit: int, expiry: int) → tuple[float, int]

    returns the starting point and the number of entries in the moving window

    Parameters:

      - key – rate limit key

      - expiry – expiry of entry

    Returns:

      (start of window, number of acquired entries)

  async acquire_sliding_window_entry(key: str, limit: int, expiry: int, amount: int = 1) → bool

    Acquire an entry if the weighted count of the current and previous windows is less than or equal to the limit

    Parameters:

      - key – rate limit key to acquire an entry in

      - limit – amount of entries allowed

      - expiry – expiry of the entry

      - amount – the number of entries to acquire

  async get_sliding_window(key: str, expiry: int) → tuple[int, float, int, float]

    Return the previous and current window information.

    Parameters:

      - key – the rate limit key

      - expiry – the rate limit expiry, needed to compute the key in some implementations

    Returns:

      a tuple of (int, float, int, float) with the following information: - previous window counter - previous window TTL - current window counter - current window TTL

  async check() → bool

    check if storage is healthy

  DEPENDENCIES: dict[str, Version | None] | list[str] = []

    The python modules this class has a dependency on. Used to lazily populate the `dependencies`

  async reset() → int | None

    reset storage to clear limits

  classmethod sliding_window_keys(key: str, expiry: int, at: float) → tuple[str, str]

    returns the previous and the current window’s keys.

    Parameters:

      - key – the key to get the window’s keys from

      - expiry – the expiry of the limit item, in seconds

      - at – the timestamp to get the keys from. Default to now, ie `time.time()`

    Returns a tuple with the previous and the current key: (previous, current).

    Example:

      - key = “mykey”

      - expiry = 60

      - at = 1738576292.6631825

    The return value will be the tuple `("mykey/28976271", "mykey/28976270")`.

#### Async Redis Storage

class RedisStorage(uri: str, wrap_exceptions: bool = False, implementation: Literal['redispy', 'coredis', 'valkey'] = 'coredis', **options: float | str | bool)

  Rate limit storage with redis as backend.

  Depends on coredis or redis

  Changed in version 4.3: Added support for using the asyncio redis client from valkey through `implementation` or if `uri` has the `async+valkey` schema

  Changed in version 4.2: Added support for using the asyncio redis client from redis through `implementation`

  Added in version 2.1.

  Parameters:

    - uri –

      uri of the form:

      - `async+redis://[:password]@host:port`

      - `async+redis://[:password]@host:port/db`

      - `async+rediss://[:password]@host:port`

      - `async+redis+unix:///path/to/sock?db=0` etc…

      This uri is passed directly to `coredis.Redis.from_url()` or

        `redis.asyncio.client.Redis.from_url()` with the initial `async` removed, except for the case of `async+redis+unix` where it is replaced with `unix`.

      If the uri scheme is `async+valkey` the implementation used will be from valkey.

    - connection_pool – if provided, the redis client is initialized with the connection pool and any other params passed as `options`

    - wrap_exceptions – Whether to wrap storage exceptions in `limits.errors.StorageError` before raising it.

    - implementation –

      Whether to use the client implementation from

      - `coredis`: `coredis.Redis`

      - `redispy`: `redis.asyncio.client.Redis`

      - `valkey`: `valkey.asyncio.client.Valkey`

    - options – all remaining keyword arguments are passed directly to the constructor of `coredis.Redis` or `redis.asyncio.client.Redis`

  Raises:

    ConfigurationError – when the redis library is not available

  STORAGE_SCHEME: list[str] | None = ['async+redis', 'async+rediss', 'async+redis+unix', 'async+valkey', 'async+valkeys', 'async+valkey+unix']

    The storage schemes for redis to be used in an async context

  DEPENDENCIES: dict[str, Version | None] | list[str] = {'coredis': <Version('3.4.0')>, 'redis': <Version('5.2.0')>, 'valkey': <Version('6.0')>}

    The python modules this class has a dependency on. Used to lazily populate the `dependencies`

  async incr(key: str, expiry: int, elastic_expiry: bool = False, amount: int = 1) → int

    increments the counter for a given rate limit key

    Parameters:

      - key – the key to increment

      - expiry – amount in seconds for the key to expire in

      - amount – the number to increment by

  async get(key: str) → int
    Parameters:

      key – the key to get the counter value for

  async clear(key: str) → None
    Parameters:

      key – the key to clear rate limits for

  async acquire_entry(key: str, limit: int, expiry: int, amount: int = 1) → bool
    Parameters:

      - key – rate limit key to acquire an entry in

      - limit – amount of entries allowed

      - expiry – expiry of the entry

      - amount – the number of entries to acquire

  async get_moving_window(key: str, limit: int, expiry: int) → tuple[float, int]

    returns the starting point and the number of entries in the moving window

    Parameters:

      - key – rate limit key

      - expiry – expiry of entry

    Returns:

      (previous count, previous TTL, current count, current TTL)

  async acquire_sliding_window_entry(key: str, limit: int, expiry: int, amount: int = 1) → bool

    Acquire an entry if the weighted count of the current and previous windows is less than or equal to the limit

    Parameters:

      - key – rate limit key to acquire an entry in

      - limit – amount of entries allowed

      - expiry – expiry of the entry

      - amount – the number of entries to acquire

  async get_sliding_window(key: str, expiry: int) → tuple[int, float, int, float]

    Return the previous and current window information.

    Parameters:

      - key – the rate limit key

      - expiry – the rate limit expiry, needed to compute the key in some implementations

    Returns:

      a tuple of (int, float, int, float) with the following information: - previous window counter - previous window TTL - current window counter - current window TTL

  async get_expiry(key: str) → float
    Parameters:

      key – the key to get the expiry for

  async check() → bool

    Check if storage is healthy by calling `PING`

  async reset() → int | None

    This function calls a Lua Script to delete keys prefixed with `self.PREFIX` in blocks of 5000.

    Warning

    This operation was designed to be fast, but was not tested on a large production based system. Be careful with its usage as it could be slow on very large data sets.

#### Async Redis Cluster Storage

class RedisClusterStorage(uri: str, wrap_exceptions: bool = False, implementation: Literal['redispy', 'coredis', 'valkey'] = 'coredis', **options: float | str | bool)

  Rate limit storage with redis cluster as backend

  Depends on coredis or redis

  Changed in version 4.3: Added support for using the asyncio redis client from valkey through `implementation` or if `uri` has the `async+valkey+cluster` schema

  Changed in version 4.2: Added support for using the asyncio redis client from redis

  Added in version 2.1.

  Parameters:

    - uri –

      url of the form `async+redis+cluster://[:password]@host:port,host:port`

      If the uri scheme is `async+valkey+cluster` the implementation used will be from valkey.

    - wrap_exceptions – Whether to wrap storage exceptions in `limits.errors.StorageError` before raising it.

    - implementation –

      Whether to use the client implementation from

      - `coredis`: `coredis.RedisCluster`

      - `redispy`: `redis.asyncio.cluster.RedisCluster`

      - `valkey`: `valkey.asyncio.cluster.ValkeyCluster`

    - options – all remaining keyword arguments are passed directly to the constructor of `coredis.RedisCluster` or `redis.asyncio.RedisCluster`

  Raises:

    ConfigurationError – when the redis library is not available or if the redis host cannot be pinged.

  STORAGE_SCHEME: list[str] | None = ['async+redis+cluster', 'async+valkey+cluster']

    The storage schemes for redis cluster to be used in an async context

  async reset() → int | None

    Redis Clusters are sharded and deleting across shards can’t be done atomically. Because of this, this reset loops over all keys that are prefixed with `self.PREFIX` and calls delete on them, one at a time.

    Warning

    This operation was not tested with extremely large data sets. On a large production based system, care should be taken with its usage as it could be slow on very large data sets

  DEPENDENCIES: dict[str, Version | None] | list[str] = {'coredis': <Version('3.4.0')>, 'redis': <Version('5.2.0')>, 'valkey': <Version('6.0')>}

    The python modules this class has a dependency on. Used to lazily populate the `dependencies`

  async acquire_entry(key: str, limit: int, expiry: int, amount: int = 1) → bool
    Parameters:

      - key – rate limit key to acquire an entry in

      - limit – amount of entries allowed

      - expiry – expiry of the entry

      - amount – the number of entries to acquire

  async acquire_sliding_window_entry(key: str, limit: int, expiry: int, amount: int = 1) → bool

    Acquire an entry if the weighted count of the current and previous windows is less than or equal to the limit

    Parameters:

      - key – rate limit key to acquire an entry in

      - limit – amount of entries allowed

      - expiry – expiry of the entry

      - amount – the number of entries to acquire

  async check() → bool

    Check if storage is healthy by calling `PING`

  async clear(key: str) → None
    Parameters:

      key – the key to clear rate limits for

  async get(key: str) → int
    Parameters:

      key – the key to get the counter value for

  async get_expiry(key: str) → float
    Parameters:

      key – the key to get the expiry for

  async get_moving_window(key: str, limit: int, expiry: int) → tuple[float, int]

    returns the starting point and the number of entries in the moving window

    Parameters:

      - key – rate limit key

      - expiry – expiry of entry

    Returns:

      (previous count, previous TTL, current count, current TTL)

  async get_sliding_window(key: str, expiry: int) → tuple[int, float, int, float]

    Return the previous and current window information.

    Parameters:

      - key – the rate limit key

      - expiry – the rate limit expiry, needed to compute the key in some implementations

    Returns:

      a tuple of (int, float, int, float) with the following information: - previous window counter - previous window TTL - current window counter - current window TTL

  async incr(key: str, expiry: int, elastic_expiry: bool = False, amount: int = 1) → int

    increments the counter for a given rate limit key

    Parameters:

      - key – the key to increment

      - expiry – amount in seconds for the key to expire in

      - amount – the number to increment by

#### Async Redis Sentinel Storage

class RedisSentinelStorage(uri: str, wrap_exceptions: bool = False, implementation: Literal['redispy', 'coredis', 'valkey'] = 'coredis', service_name: str | None = None, use_replicas: bool = True, sentinel_kwargs: dict[str, float | str | bool] | None = None, **options: float | str | bool)

  Rate limit storage with redis sentinel as backend

  Depends on coredis or redis

  Changed in version 4.3: Added support for using the asyncio redis client from valkey through `implementation` or if `uri` has the `async+valkey+sentinel` schema

  Changed in version 4.2: Added support for using the asyncio redis client from redis

  Added in version 2.1.

  Parameters:

    - uri –

      url of the form `async+redis+sentinel://host:port,host:port/service_name`

      If the uri schema is `async+valkey+sentinel` the implementation used will be from valkey.

    - wrap_exceptions – Whether to wrap storage exceptions in `limits.errors.StorageError` before raising it.

    - implementation –

      Whether to use the client implementation from

      - `coredis`: `coredis.sentinel.Sentinel`

      - `redispy`: `redis.asyncio.sentinel.Sentinel`

      - `valkey`: `valkey.asyncio.sentinel.Sentinel`

    - service_name – sentinel service name (if not provided in uri)

    - use_replicas – Whether to use replicas for read only operations

    - sentinel_kwargs – optional arguments to pass as sentinel_kwargs` to `coredis.sentinel.Sentinel` or `redis.asyncio.Sentinel`

    - options – all remaining keyword arguments are passed directly to the constructor of `coredis.sentinel.Sentinel` or `redis.asyncio.sentinel.Sentinel`

  Raises:

    ConfigurationError – when the redis library is not available or if the redis primary host cannot be pinged.

  STORAGE_SCHEME: list[str] | None = ['async+redis+sentinel', 'async+valkey+sentinel']

    The storage scheme for redis accessed via a redis sentinel installation

  async acquire_entry(key: str, limit: int, expiry: int, amount: int = 1) → bool
    Parameters:

      - key – rate limit key to acquire an entry in

      - limit – amount of entries allowed

      - expiry – expiry of the entry

      - amount – the number of entries to acquire

  async acquire_sliding_window_entry(key: str, limit: int, expiry: int, amount: int = 1) → bool

    Acquire an entry if the weighted count of the current and previous windows is less than or equal to the limit

    Parameters:

      - key – rate limit key to acquire an entry in

      - limit – amount of entries allowed

      - expiry – expiry of the entry

      - amount – the number of entries to acquire

  async check() → bool

    Check if storage is healthy by calling `PING`

  async clear(key: str) → None
    Parameters:

      key – the key to clear rate limits for

  async get(key: str) → int
    Parameters:

      key – the key to get the counter value for

  async get_expiry(key: str) → float
    Parameters:

      key – the key to get the expiry for

  async get_moving_window(key: str, limit: int, expiry: int) → tuple[float, int]

    returns the starting point and the number of entries in the moving window

    Parameters:

      - key – rate limit key

      - expiry – expiry of entry

    Returns:

      (previous count, previous TTL, current count, current TTL)

  async get_sliding_window(key: str, expiry: int) → tuple[int, float, int, float]

    Return the previous and current window information.

    Parameters:

      - key – the rate limit key

      - expiry – the rate limit expiry, needed to compute the key in some implementations

    Returns:

      a tuple of (int, float, int, float) with the following information: - previous window counter - previous window TTL - current window counter - current window TTL

  async incr(key: str, expiry: int, elastic_expiry: bool = False, amount: int = 1) → int

    increments the counter for a given rate limit key

    Parameters:

      - key – the key to increment

      - expiry – amount in seconds for the key to expire in

      - amount – the number to increment by

  async reset() → int | None

    This function calls a Lua Script to delete keys prefixed with `self.PREFIX` in blocks of 5000.

    Warning

    This operation was designed to be fast, but was not tested on a large production based system. Be careful with its usage as it could be slow on very large data sets.

  DEPENDENCIES: dict[str, Version | None] | list[str] = {'coredis': <Version('3.4.0')>, 'coredis.sentinel': <Version('3.4.0')>, 'redis': <Version('5.2.0')>, 'valkey': <Version('6.0')>}

    The python modules this class has a dependency on. Used to lazily populate the `dependencies`

#### Async Memcached Storage

class MemcachedStorage(uri: str, wrap_exceptions: bool = False, **options: float | str | bool)

  Rate limit storage with memcached as backend.

  Depends on emcache

  Added in version 2.1.

  Parameters:

    - uri – memcached location of the form `async+memcached://host:port,host:port`

    - wrap_exceptions – Whether to wrap storage exceptions in `limits.errors.StorageError` before raising it.

    - options – all remaining keyword arguments are passed directly to the constructor of `emcache.Client`

  Raises:

    ConfigurationError – when emcache is not available

  STORAGE_SCHEME: list[str] | None = ['async+memcached']

    The storage scheme for memcached to be used in an async context

  DEPENDENCIES: dict[str, Version | None] | list[str] = ['emcache']

    The python modules this class has a dependency on. Used to lazily populate the `dependencies`

  async get(key: str) → int
    Parameters:

      key – the key to get the counter value for

  async get_many(keys: Iterable[str]) → dict[bytes, ItemP]

    Return multiple counters at once

    Parameters:

      keys – the keys to get the counter values for

  async clear(key: str) → None
    Parameters:

      key – the key to clear rate limits for

  async decr(key: str, amount: int = 1, noreply: bool = False) → int

    decrements the counter for a given rate limit key

    retursn 0 if the key doesn’t exist or if noreply is set to True

    Parameters:

      - key – the key to decrement

      - amount – the number to decrement by

      - noreply – set to True to ignore the memcached response

  async incr(key: str, expiry: float, elastic_expiry: bool = False, amount: int = 1, set_expiration_key: bool = True) → int

    increments the counter for a given rate limit key

    Parameters:

      - key – the key to increment

      - expiry – amount in seconds for the key to expire in

      - elastic_expiry – whether to keep extending the rate limit window every hit.

      - amount – the number to increment by

      - set_expiration_key – if set to False, the expiration time won’t be stored but the key will still expire

  async get_expiry(key: str) → float
    Parameters:

      key – the key to get the expiry for

  async check() → bool

    Check if storage is healthy by calling the `get` command on the key `limiter-check`

  async reset() → int | None

    reset storage to clear limits

  async acquire_sliding_window_entry(key: str, limit: int, expiry: int, amount: int = 1) → bool

    Acquire an entry if the weighted count of the current and previous windows is less than or equal to the limit

    Parameters:

      - key – rate limit key to acquire an entry in

      - limit – amount of entries allowed

      - expiry – expiry of the entry

      - amount – the number of entries to acquire

  async get_sliding_window(key: str, expiry: int) → tuple[int, float, int, float]

    Return the previous and current window information.

    Parameters:

      - key – the rate limit key

      - expiry – the rate limit expiry, needed to compute the key in some implementations

    Returns:

      a tuple of (int, float, int, float) with the following information: - previous window counter - previous window TTL - current window counter - current window TTL

  classmethod sliding_window_keys(key: str, expiry: int, at: float) → tuple[str, str]

    returns the previous and the current window’s keys.

    Parameters:

      - key – the key to get the window’s keys from

      - expiry – the expiry of the limit item, in seconds

      - at – the timestamp to get the keys from. Default to now, ie `time.time()`

    Returns a tuple with the previous and the current key: (previous, current).

    Example:

      - key = “mykey”

      - expiry = 60

      - at = 1738576292.6631825

    The return value will be the tuple `("mykey/28976271", "mykey/28976270")`.

#### Async MongoDB Storage

class MongoDBStorage(uri: str, database_name: str = 'limits', counter_collection_name: str = 'counters', window_collection_name: str = 'windows', wrap_exceptions: bool = False, **options: float | str | bool)

  Rate limit storage with MongoDB as backend.

  Depends on motor

  Changed in version 3.14.0: Added option to select custom collection names for windows & counters

  Added in version 2.1.

  Parameters:

    - uri – uri of the form `async+mongodb://[user:password]@host:port?...`, This uri is passed directly to `AsyncIOMotorClient`

    - database_name – The database to use for storing the rate limit collections.

    - counter_collection_name – The collection name to use for individual counters used in fixed window strategies

    - window_collection_name – The collection name to use for sliding & moving window storage

    - wrap_exceptions – Whether to wrap storage exceptions in `limits.errors.StorageError` before raising it.

    - options – all remaining keyword arguments are passed to the constructor of `AsyncIOMotorClient`

  Raises:

    ConfigurationError – when the motor or pymongo are not available

  STORAGE_SCHEME: list[str] | None = ['async+mongodb', 'async+mongodb+srv']

    The storage scheme for MongoDB for use in an async context

  DEPENDENCIES: dict[str, Version | None] | list[str] = ['motor.motor_asyncio', 'pymongo']

    The python modules this class has a dependency on. Used to lazily populate the `dependencies`

  async reset() → int | None

    Delete all rate limit keys in the rate limit collections (counters, windows)

  async clear(key: str) → None
    Parameters:

      key – the key to clear rate limits for

  async get_expiry(key: str) → float
    Parameters:

      key – the key to get the expiry for

  async get(key: str) → int
    Parameters:

      key – the key to get the counter value for

  async incr(key: str, expiry: int, elastic_expiry: bool = False, amount: int = 1) → int

    increments the counter for a given rate limit key

    Parameters:

      - key – the key to increment

      - expiry – amount in seconds for the key to expire in

      - elastic_expiry – whether to keep extending the rate limit window every hit.

      - amount – the number to increment by

  async check() → bool

    Check if storage is healthy by calling `motor.motor_asyncio.AsyncIOMotorClient.server_info()`

  async get_moving_window(key: str, limit: int, expiry: int) → tuple[float, int]

    returns the starting point and the number of entries in the moving window

    Parameters:

      - key (str) – rate limit key

      - expiry (int) – expiry of entry

    Returns:

      (start of window, number of acquired entries)

  async acquire_entry(key: str, limit: int, expiry: int, amount: int = 1) → bool
    Parameters:

      - key – rate limit key to acquire an entry in

      - limit – amount of entries allowed

      - expiry – expiry of the entry

      - amount – the number of entries to acquire

  async acquire_sliding_window_entry(key: str, limit: int, expiry: int, amount: int = 1) → bool

    Acquire an entry if the weighted count of the current and previous windows is less than or equal to the limit

    Parameters:

      - key – rate limit key to acquire an entry in

      - limit – amount of entries allowed

      - expiry – expiry of the entry

      - amount – the number of entries to acquire

  async get_sliding_window(key: str, expiry: int) → tuple[int, float, int, float]

    Return the previous and current window information.

    Parameters:

      - key – the rate limit key

      - expiry – the rate limit expiry, needed to compute the key in some implementations

    Returns:

      a tuple of (int, float, int, float) with the following information: - previous window counter - previous window TTL - current window counter - current window TTL

#### Async Etcd Storage

class EtcdStorage(*args, **kwargs)

  Rate limit storage with etcd as backend.

  Depends on aetcd.

  Deprecated since version 4.4.

  Parameters:

    - uri – etcd location of the form `async+etcd://host:port`,

    - max_retries – Maximum number of attempts to retry in the case of concurrent updates to a rate limit key

    - wrap_exceptions – Whether to wrap storage exceptions in `limits.errors.StorageError` before raising it.

    - options – all remaining keyword arguments are passed directly to the constructor of `aetcd.client.Client`

  Raises:

    ConfigurationError – when aetcd is not available

  STORAGE_SCHEME: list[str] | None = ['async+etcd']

    The async storage scheme for etcd

  DEPENDENCIES: dict[str, Version | None] | list[str] = ['aetcd']

    The python modules this class has a dependency on. Used to lazily populate the `dependencies`

  async incr(key: str, expiry: int, elastic_expiry: bool = False, amount: int = 1) → int

    increments the counter for a given rate limit key

    Parameters:

      - key – the key to increment

      - expiry – amount in seconds for the key to expire in

      - elastic_expiry – whether to keep extending the rate limit window every hit.

      - amount – the number to increment by

  async get(key: str) → int
    Parameters:

      key – the key to get the counter value for

  async get_expiry(key: str) → float
    Parameters:

      key – the key to get the expiry for

  async check() → bool

    check if storage is healthy

  async reset() → int | None

    reset storage to clear limits

  async clear(key: str) → None

    resets the rate limit key

    Parameters:

      key – the key to clear rate limits for

### Abstract storage classes

class Storage(uri: str | None = None, wrap_exceptions: bool = False, **options: float | str | bool)

  Base class to extend when implementing a storage backend.

  Parameters:

    wrap_exceptions – Whether to wrap storage exceptions in `limits.errors.StorageError` before raising it.

  STORAGE_SCHEME: list[str] | None

    The storage schemes to register against this implementation

  abstractmethod incr(key: str, expiry: int, elastic_expiry: bool = False, amount: int = 1) → int

    increments the counter for a given rate limit key

    Parameters:

      - key – the key to increment

      - expiry – amount in seconds for the key to expire in

      - elastic_expiry – whether to keep extending the rate limit window every hit.

      - amount – the number to increment by

  abstractmethod get(key: str) → int
    Parameters:

      key – the key to get the counter value for

  abstractmethod get_expiry(key: str) → float
    Parameters:

      key – the key to get the expiry for

  abstractmethod check() → bool

    check if storage is healthy

  abstractmethod reset() → int | None

    reset storage to clear limits

  abstractmethod clear(key: str) → None

    resets the rate limit key

    Parameters:

      key – the key to clear rate limits for

  DEPENDENCIES: dict[str, Version | None] | list[str] = []

    The python modules this class has a dependency on. Used to lazily populate the `dependencies`

class MovingWindowSupport

  Abstract base class for storages that support the Moving Window strategy

  abstractmethod acquire_entry(key: str, limit: int, expiry: int, amount: int = 1) → bool
    Parameters:

      - key – rate limit key to acquire an entry in

      - limit – amount of entries allowed

      - expiry – expiry of the entry

      - amount – the number of entries to acquire

  abstractmethod get_moving_window(key: str, limit: int, expiry: int) → tuple[float, int]

    returns the starting point and the number of entries in the moving window

    Parameters:

      - key – rate limit key

      - expiry – expiry of entry

    Returns:

      (start of window, number of acquired entries)

class SlidingWindowCounterSupport

  Abstract base class for storages that support the Sliding Window Counter strategy.

  abstractmethod acquire_sliding_window_entry(key: str, limit: int, expiry: int, amount: int = 1) → bool

    Acquire an entry if the weighted count of the current and previous windows is less than or equal to the limit

    Parameters:

      - key – rate limit key to acquire an entry in

      - limit – amount of entries allowed

      - expiry – expiry of the entry

      - amount – the number of entries to acquire

  abstractmethod get_sliding_window(key: str, expiry: int) → tuple[int, float, int, float]

    Return the previous and current window information.

    Parameters:

      - key – the rate limit key

      - expiry – the rate limit expiry, needed to compute the key in some implementations

    Returns:

      a tuple of (int, float, int, float) with the following information: - previous window counter - previous window TTL - current window counter - current window TTL

### Async Abstract storage classes

class Storage(uri: str | None = None, wrap_exceptions: bool = False, **options: float | str | bool)

  Base class to extend when implementing an async storage backend.

  Added in version 2.1.

  Parameters:

    wrap_exceptions – Whether to wrap storage exceptions in `limits.errors.StorageError` before raising it.

  STORAGE_SCHEME: list[str] | None

    The storage schemes to register against this implementation

  abstractmethod async incr(key: str, expiry: int, elastic_expiry: bool = False, amount: int = 1) → int

    increments the counter for a given rate limit key

    Parameters:

      - key – the key to increment

      - expiry – amount in seconds for the key to expire in

      - elastic_expiry – whether to keep extending the rate limit window every hit.

      - amount – the number to increment by

  abstractmethod async get(key: str) → int
    Parameters:

      key – the key to get the counter value for

  abstractmethod async get_expiry(key: str) → float
    Parameters:

      key – the key to get the expiry for

  abstractmethod async check() → bool

    check if storage is healthy

  abstractmethod async reset() → int | None

    reset storage to clear limits

  abstractmethod async clear(key: str) → None

    resets the rate limit key

    Parameters:

      key – the key to clear rate limits for

  DEPENDENCIES: dict[str, Version | None] | list[str] = []

    The python modules this class has a dependency on. Used to lazily populate the `dependencies`

class MovingWindowSupport

  Abstract base class for async storages that support the Moving Window strategy

  abstractmethod async acquire_entry(key: str, limit: int, expiry: int, amount: int = 1) → bool
    Parameters:

      - key – rate limit key to acquire an entry in

      - limit – amount of entries allowed

      - expiry – expiry of the entry

      - amount – the number of entries to acquire

  abstractmethod async get_moving_window(key: str, limit: int, expiry: int) → tuple[float, int]

    returns the starting point and the number of entries in the moving window

    Parameters:

      - key – rate limit key

      - expiry – expiry of entry

    Returns:

      (start of window, number of acquired entries)

class SlidingWindowCounterSupport

  Abstract base class for async storages that support the Sliding Window Counter strategy

  abstractmethod async acquire_sliding_window_entry(key: str, limit: int, expiry: int, amount: int = 1) → bool

    Acquire an entry if the weighted count of the current and previous windows is less than or equal to the limit

    Parameters:

      - key – rate limit key to acquire an entry in

      - limit – amount of entries allowed

      - expiry – expiry of the entry

      - amount – the number of entries to acquire

  abstractmethod async get_sliding_window(key: str, expiry: int) → tuple[int, float, int, float]

    Return the previous and current window information.

    Parameters:

      - key – the rate limit key

      - expiry – the rate limit expiry, needed to compute the key in some implementations

    Returns:

      a tuple of (int, float, int, float) with the following information: - previous window counter - previous window TTL - current window counter - current window TTL

## Rate Limits

Provided by `limits`

### Parsing functions

parse(limit_string: str) → RateLimitItem

  parses a single rate limit in string notation (e.g. `1/second` or `1 per second`)

  Parameters:

    limit_string – rate limit string using Rate limit string notation

  Raises:

    ValueError – if the string notation is invalid.

parse_many(limit_string: str) → list[RateLimitItem]

  parses rate limits in string notation containing multiple rate limits (e.g. `1/second; 5/minute`)

  Parameters:

    limit_string – rate limit string using Rate limit string notation

  Raises:

    ValueError – if the string notation is invalid.

### Rate limit granularities

All rate limit items implement `RateLimitItem` by declaring a `GRANULARITY`

class RateLimitItem(amount: int, multiples: int | None = 1, namespace: str = 'LIMITER')

  defines a Rate limited resource which contains the characteristic namespace, amount and granularity multiples of the rate limiting window.

  Parameters:

    - amount – the rate limit amount

    - multiples – multiple of the ‘per’ `GRANULARITY` (e.g. ‘n’ per ‘m’ seconds)

    - namespace – category for the specific rate limit

  GRANULARITY: ClassVar[Granularity]

    A tuple describing the granularity of this limit as (number of seconds, name)

  classmethod check_granularity_string(granularity_string: str) → bool

    Checks if this instance matches a granularity_string of type `n per hour`, `n per minute` etc, by comparing with `GRANULARITY`

  get_expiry() → int
    Returns:

      the duration the limit is enforced for in seconds.

  key_for(*identifiers: bytes | str | int | float) → str

    Constructs a key for the current limit and any additional identifiers provided.

    Parameters:

      identifiers – a list of strings to append to the key

    Returns:

      a string key identifying this resource with each identifier separated with a ‘/’ delimiter.

class RateLimitItemPerSecond(amount: int, multiples: int | None = 1, namespace: str = 'LIMITER')

  per second rate limited resource.

  classmethod check_granularity_string(granularity_string: str) → bool

    Checks if this instance matches a granularity_string of type `n per hour`, `n per minute` etc, by comparing with `GRANULARITY`

  get_expiry() → int
    Returns:

      the duration the limit is enforced for in seconds.

  key_for(*identifiers: bytes | str | int | float) → str

    Constructs a key for the current limit and any additional identifiers provided.

    Parameters:

      identifiers – a list of strings to append to the key

    Returns:

      a string key identifying this resource with each identifier separated with a ‘/’ delimiter.

  GRANULARITY: ClassVar[Granularity] = (1, 'second')

    A second

class RateLimitItemPerMinute(amount: int, multiples: int | None = 1, namespace: str = 'LIMITER')

  per minute rate limited resource.

  classmethod check_granularity_string(granularity_string: str) → bool

    Checks if this instance matches a granularity_string of type `n per hour`, `n per minute` etc, by comparing with `GRANULARITY`

  get_expiry() → int
    Returns:

      the duration the limit is enforced for in seconds.

  key_for(*identifiers: bytes | str | int | float) → str

    Constructs a key for the current limit and any additional identifiers provided.

    Parameters:

      identifiers – a list of strings to append to the key

    Returns:

      a string key identifying this resource with each identifier separated with a ‘/’ delimiter.

  GRANULARITY: ClassVar[Granularity] = (60, 'minute')

    A minute

class RateLimitItemPerHour(amount: int, multiples: int | None = 1, namespace: str = 'LIMITER')

  per hour rate limited resource.

  GRANULARITY: ClassVar[Granularity] = (3600, 'hour')

    An hour

  classmethod check_granularity_string(granularity_string: str) → bool

    Checks if this instance matches a granularity_string of type `n per hour`, `n per minute` etc, by comparing with `GRANULARITY`

  get_expiry() → int
    Returns:

      the duration the limit is enforced for in seconds.

  key_for(*identifiers: bytes | str | int | float) → str

    Constructs a key for the current limit and any additional identifiers provided.

    Parameters:

      identifiers – a list of strings to append to the key

    Returns:

      a string key identifying this resource with each identifier separated with a ‘/’ delimiter.

class RateLimitItemPerDay(amount: int, multiples: int | None = 1, namespace: str = 'LIMITER')

  per day rate limited resource.

  GRANULARITY: ClassVar[Granularity] = (86400, 'day')

    A day

  classmethod check_granularity_string(granularity_string: str) → bool

    Checks if this instance matches a granularity_string of type `n per hour`, `n per minute` etc, by comparing with `GRANULARITY`

  get_expiry() → int
    Returns:

      the duration the limit is enforced for in seconds.

  key_for(*identifiers: bytes | str | int | float) → str

    Constructs a key for the current limit and any additional identifiers provided.

    Parameters:

      identifiers – a list of strings to append to the key

    Returns:

      a string key identifying this resource with each identifier separated with a ‘/’ delimiter.

class RateLimitItemPerMonth(amount: int, multiples: int | None = 1, namespace: str = 'LIMITER')

  per month rate limited resource.

  GRANULARITY: ClassVar[Granularity] = (2592000, 'month')

    A month

  classmethod check_granularity_string(granularity_string: str) → bool

    Checks if this instance matches a granularity_string of type `n per hour`, `n per minute` etc, by comparing with `GRANULARITY`

  get_expiry() → int
    Returns:

      the duration the limit is enforced for in seconds.

  key_for(*identifiers: bytes | str | int | float) → str

    Constructs a key for the current limit and any additional identifiers provided.

    Parameters:

      identifiers – a list of strings to append to the key

    Returns:

      a string key identifying this resource with each identifier separated with a ‘/’ delimiter.

class RateLimitItemPerYear(amount: int, multiples: int | None = 1, namespace: str = 'LIMITER')

  per year rate limited resource.

  GRANULARITY: ClassVar[Granularity] = (31104000, 'year')

    A year

  classmethod check_granularity_string(granularity_string: str) → bool

    Checks if this instance matches a granularity_string of type `n per hour`, `n per minute` etc, by comparing with `GRANULARITY`

  get_expiry() → int
    Returns:

      the duration the limit is enforced for in seconds.

  key_for(*identifiers: bytes | str | int | float) → str

    Constructs a key for the current limit and any additional identifiers provided.

    Parameters:

      identifiers – a list of strings to append to the key

    Returns:

      a string key identifying this resource with each identifier separated with a ‘/’ delimiter.

## Structures

class WindowStats(reset_time: float, remaining: int)

  tuple to describe a rate limited window

  Create new instance of WindowStats(reset_time, remaining)

  reset_time: float

    Time as seconds since the Epoch when this window will be reset

  remaining: int

    Quantity remaining in this window

## Exceptions

exception ConfigurationError

  Error raised when a configuration problem is encountered

exception ConcurrentUpdateError(key: str, attempts: int)

  Error raised when an update to limit fails due to concurrent updates

exception StorageError(storage_error: Exception)

  Error raised when an error is encountered in a storage