Concurrency
Understand how many cloro requests can run at once, how that ceiling differs from the per-minute rate limit, and how to read both straight from the response headers to keep your workers busy without tripping a 429.
Concurrency vs. rate limits
The cloro API enforces two independent ceilings, and it helps to keep them separate in your head. The concurrency limit caps how many requests may be in flight at the same instant — the moment one finishes, a slot frees up. The rate limit caps how many requests you may start within a rolling time window, regardless of whether earlier ones have completed. A batch job can sit comfortably under its rate limit and still stall because every concurrency slot is occupied, so tune both when you scale out.
Reading the headers
Every response from an authenticated endpoint carries a small set of headers that report your current standing. Poll them from any successful call — there is no separate metering endpoint to hit — and let your workers back off before a limit is reached rather than after.
| Field | Type | Description |
|---|---|---|
| X-Concurrent-Limit | integer | Maximum number of requests your account may run simultaneously. |
| X-Concurrent-Current | integer | How many requests are active at the moment this response was produced. |
| X-Concurrent-Remaining | integer | Free slots still available before the concurrency ceiling is hit. |
| X-RateLimit-Limit | integer | Total requests permitted within the current rolling window. |
| X-RateLimit-Remaining | integer | Requests left in the window before further calls are rejected. |
Response example
HTTP/1.1 200 OK
Content-Type: application/json
X-Concurrent-Limit: 20
X-Concurrent-Current: 13
X-Concurrent-Remaining: 7
X-RateLimit-Limit: 600
X-RateLimit-Remaining: 421
{
"id": "req_9f2a7c41",
"object": "search.result",
"status": "completed",
"created": 1734105600
}
Handling backpressure
When either ceiling is exceeded the API answers with HTTP 429. Treat that status as a signal to pause and retry, not as a hard failure. A practical worker pool watches X-Concurrent-Remaining and holds new jobs whenever it falls to zero, then resumes as soon as a later response reports headroom again. Pairing that with exponential backoff on any 429 keeps throughput close to the maximum your plan allows while staying inside both limits.
Notes
- Header values reflect the state at response time; under heavy parallelism they can shift between two nearly simultaneous calls, so read them per response rather than caching a snapshot.
- The concurrency and rate ceilings scale with your plan. If your workloads routinely saturate either one, reach out to [email protected] to review higher tiers.