# Rate limits and concurrency

> What bounds how many tasks you can run and how often you can read them, the RateLimit headers that say where you stand, and how to run many tasks at once.

Source: https://zerocaptcha.io/docs/rate-limits

There is no rate limit on creating paid tasks. What bounds your throughput is your balance, your
account's share of the queue, and budgets on reads. This page says what each one is, how the API
tells you where you stand, and how to run many tasks at once without hitting any of them.

## Creating tasks

| Bound | Default | Over it |
| --- | --- | --- |
| Your available balance | Your balance, less what running tasks hold | [`insufficient_funds`](https://zerocaptcha.io/docs/reference/errors#insufficient_funds) (402), `ERROR_ZERO_BALANCE` |
| A key's daily spend cap | None, until you set one | [`spend_cap_reached`](https://zerocaptcha.io/docs/reference/errors#spend_cap_reached) (402), `ERROR_SPEND_CAP_REACHED` |
| Tasks queued or running for your account | 50 at once | [`queue_full`](https://zerocaptcha.io/docs/reference/errors#queue_full) (429, `Retry-After: 2`), `ERROR_NO_SLOT_AVAILABLE` |
| Tasks queued across the service | 5,000 | `queue_full`, as above |

Creating a task draws on no request budget: the bounds above are the only ones. A task finishes
(and frees its place in your share) as soon as it succeeds, fails or expires. The share is set per
account; if you need more than 50 tasks in flight at once, [write to us](https://zerocaptcha.io/contact).

## Reading tasks and the balance

Reads (`GET /v1/tasks`, `GET /v1/tasks/{id}`, `GET /v1/balance`, `getTaskResult`, `getBalance`,
`res.php`, and opening a live-update stream) draw on two budgets: one for the key, one for its
account. Both refill evenly, not all at once when a window ends.

| Budget | Default |
| --- | --- |
| Reads per key | 200 every 2 seconds |
| Reads per account, all its keys together | 200 every 2 seconds |
| Live-update streams open per account | 10 |
| Public reads (`GET /v1/prices`, `GET /v1/status`) per client address | 60 a minute |

Over a budget, a read is refused with [`rate_limited`](https://zerocaptcha.io/docs/reference/errors#rate_limited) (429)
and `Retry-After`; in the createTask format with `ERROR_RATE_LIMIT`, and in 2Captcha's with
`ERROR: 1005` (and `MAX_USER_TURN` for `in.php`, should creation ever have a budget). Nothing is
charged for a refused read.

## Where you stand: the RateLimit headers

Replies to calls with a key carry two headers (IETF's RateLimit fields):

```text
RateLimit-Policy: "key-read";q=200;w=2, "account-read";q=200;w=2
RateLimit: "key-read";r=187;t=1, "account-read";r=161;t=1
```

- `RateLimit-Policy` names each budget with its size `q` and the seconds `w` it refills over.
- `RateLimit` says how many units `r` are left in each, and `t`, the seconds until one more is back.

Read them rather than hard-coding the defaults above, which the service may change. When `r`
reaches 0, wait `t` seconds before the next read.

## Other limits

- A request body may be at most 64 KiB; a larger one is refused with
  [`payload_too_large`](https://zerocaptcha.io/docs/reference/errors#payload_too_large) (413).
- The API answers every request within 10 seconds, or with
  [`request_timeout`](https://zerocaptcha.io/docs/reference/errors#request_timeout) (504). When it is overloaded it
  answers [`service_unavailable`](https://zerocaptcha.io/docs/reference/errors#service_unavailable) (503) with
  `Retry-After`. Retry both.

[Limits](https://zerocaptcha.io/docs/reference/limits) lists every limit in one table, field lengths included.

## Running many tasks at once

- **Create in parallel, up to your share.** Keep at most 50 tasks queued or running; when one ends,
  start the next. A worker pool of that size, or a semaphore, does it.
- **Poll each task every 2 seconds,** not faster. 50 tasks polled every 2 seconds is 25 reads a
  second, well within the read budget. Better still, use [callbacks](https://zerocaptcha.io/docs/callbacks) or one
  [live-update stream](https://zerocaptcha.io/docs/callbacks#live-updates) instead of polling each task.
- **Treat `queue_full` as back-pressure:** wait the 2 seconds it asks, then try again, and lower
  your concurrency if it keeps happening.
- **Keep enough balance** for the tasks you run at once: each holds its price until it ends.
- **Spread across keys only for bookkeeping.** Every key of an account shares the account's read
  budget and queue share, so more keys do not mean more throughput.
