Which path fits your workload
Concurrent Responses API
You want results streaming back as each request finishes, need per-request control, or care about latency on individual items. You manage concurrency on your client.
Batch API
You have a fixed set of requests and would rather submit once and collect results later. Valar owns the queue; you poll for status.
zai-org/GLM-5.2-FP8.
Fan out with the Responses API
Submit each request individually withbackground=True and run many in flight at once. For workloads of roughly 1,000 requests and up, four practices keep it stable:
- Use
AsyncOpenAIwithDefaultAioHttpClient(). Under high concurrency the SDK’s aiohttp backend outperforms the defaulthttpxtransport. - Bound concurrency with an
asyncio.Semaphore. A fixed limit (200 is a sound starting point) caps simultaneous connections so you never exhaust them. - Submit all requests behind the semaphore, collect the response IDs, then poll in a second pass. Separating submission from polling keeps both phases simple.
- Attach an
Idempotency-Keyper request so a retry after a transient failure replays the reservation rather than paying for inference twice. See Idempotent Requests.
Hand off a bundle with the Batch API
The Batch API takes up to 100,000 requests in one call, with a ceiling of 256 MB per batch. The lifecycle is three operations:1
Submit
Bundle every request into a single
POST /batches.2
Poll
Call
GET /batches/{batch_id} until every request has settled.3
Retrieve
Pull each result with
GET /batches/{batch_id}/{custom_id}.GET /batches. Include an Idempotency-Key header on submission so a client retry after a dropped connection replays your original reservation instead of creating a duplicate batch. See Idempotent Requests.
This version scores the same review backlog as one batch: