Skip to main content
When you need to process large volumes of requests — for batch evaluation, dataset generation, or production workloads — use Python’s asyncio with aiohttp to run thousands of concurrent calls against KiosAPI from a single script. This approach gives you connection pooling, fine-grained flow control, and the throughput needed for demanding pipelines.

Installation

Install the required packages:
httpx is less efficient than aiohttp for high-concurrency workloads. For best performance, use aiohttp with a single shared ClientSession as shown below.

Full Example

The example below demonstrates the recommended pattern: a shared ClientSession for connection pooling, a Semaphore to cap in-flight requests, and a while True loop that continuously drains your prompt source until it is exhausted.

Key Design Points

Three architectural decisions make this pattern reliable at scale:
  • Single shared ClientSession — create one aiohttp.ClientSession and reuse it for every request. This enables HTTP connection pooling and dramatically reduces per-request overhead compared to opening a new session each time.
  • Semaphore for concurrency control — caps the number of in-flight requests at MAX_CONCURRENCY, preventing resource exhaustion on both the client and the server.
  • while True loop — continuously pulls the next batch of prompts until your source is exhausted. Replace generate_prompts() with your own logic: a file reader, message queue consumer, or any other iterable source.

Limits and Best Practices

Do not exceed 5,000 concurrent requests in a single script. Beyond this threshold, Python’s single-threaded event loop and OS socket limits become bottlenecks, leading to timeouts and degraded throughput.
If you need more than 5,000 concurrent requests, run multiple scripts in parallel instead of raising the concurrency limit of a single process. For example, run three scripts each with MAX_CONCURRENCY = 2000 to reach ~6,000 concurrent requests across separate processes.

Error Handling

At high concurrency, individual request failures are expected. Always pass return_exceptions=True to asyncio.gather and implement retries with exponential backoff for transient errors such as 429, 500, 502, and 503.