{"id":1311,"library":"aiolimiter","title":"aiolimiter: Asyncio Rate Limiter","description":"aiolimiter is an asyncio-compatible rate limiter library for Python, implementing a leaky bucket algorithm. It allows controlling the rate at which concurrent operations can acquire permits, preventing resource exhaustion or API overuse. The current version is 1.2.1, and it maintains a steady release cadence for bug fixes and minor enhancements.","status":"active","version":"1.2.1","language":"en","source_language":"en","source_url":"https://github.com/mjpieters/aiolimiter","tags":["asyncio","rate-limiting","concurrency","networking"],"install":[{"cmd":"pip install aiolimiter","lang":"bash","label":"Install latest version"}],"dependencies":[],"imports":[{"symbol":"AsyncLimiter","correct":"from aiolimiter import AsyncLimiter"}],"quickstart":{"code":"import asyncio\nfrom aiolimiter import AsyncLimiter\n\nasync def main():\n    # Initialize a limiter for 5 permits per second\n    limiter = AsyncLimiter(5, 1) \n\n    print(\"Attempting to acquire 3 permits...\")\n    async with limiter:\n        await limiter.acquire(2) # Acquire 2 permits within the context manager\n        print(\"Acquired 3 permits (1 from 'async with', 2 from 'acquire')!\")\n\n    print(\"Attempting to acquire 1 permit without context manager...\")\n    await limiter.acquire(1)\n    print(\"Acquired 1 permit!\")\n\n    # Demonstrate waiting if limit is reached\n    print(\"Acquiring 5 permits, might wait...\")\n    for _ in range(5):\n        await limiter.acquire(1)\n        print(f\"Permit {_+1} acquired.\")\n\nasyncio.run(main())","lang":"python","description":"This quickstart demonstrates how to initialize `AsyncLimiter` and use it to control the rate of operations. It shows both the `async with` context manager for single-permit acquisition and the explicit `await limiter.acquire(count)` method for multiple permits."},"warnings":[{"fix":"Always use `await limiter.acquire(count)` for explicit permit acquisition.","message":"When using `limiter.acquire(count)` outside of an `async with` block, it must be `await`ed, as it is a coroutine. Forgetting `await` will result in a runtime warning about an unawaited coroutine, or the acquisition not taking effect as intended.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"Ensure `rate` is the quantity of permits and `period` is the time window. For 'X events per Y seconds', use `AsyncLimiter(X, Y)`.","message":"The `rate` and `period` parameters of `AsyncLimiter(rate, period)` can be confused. `rate` is the number of permits, and `period` is the duration in seconds over which those permits are available. E.g., `AsyncLimiter(10, 1)` means 10 permits per 1 second, not 1 permit per 10 seconds.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"Wrap `await limiter.acquire(count, block=False)` in a `try...except LimitReached` block to handle cases where permits cannot be acquired instantly.","message":"By default, `acquire()` blocks until permits are available. If you want a non-blocking attempt, pass `block=False`. In this case, if permits are not immediately available, `acquire()` will raise a `LimitReached` exception instead of waiting.","severity":"gotcha","affected_versions":">=1.0.0"}],"env_vars":null,"last_verified":"2026-04-09T00:00:00.000Z","next_check":"2026-07-08T00:00:00.000Z"}