> ## Documentation Index
> Fetch the complete documentation index at: https://docs.priorlabs.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Rate limits

> Default per-user request limits for TabPFN API uploads, fits, and predictions.

The TabPFN API applies per-user request limits to keep the service reliable and responsive. Each operation must remain below both its per-minute and per-hour limit.

These request limits are separate from [API metering](/api-reference/metering), which tracks prediction tokens and thinking fits over daily and monthly periods. Exceeding either a request rate limit or a usage quota returns **HTTP 429**.

***

## Default limits

| Request type                                     | Requests per minute | Requests per hour |
| ------------------------------------------------ | ------------------: | ----------------: |
| Predict                                          |                  60 |             1,500 |
| Fit                                              |                  60 |             1,000 |
| [Thinking mode](/capabilities/thinking-mode) fit |                  10 |                30 |
| Upload                                           |                 120 |             3,000 |

Both limits apply at the same time. For example, you can stay below the per-minute prediction limit, but still breach the hourly limit.

A thinking mode fit counts against both the thinking fit limit and the general fit limit. Train- and test-set upload preparation requests share the upload limit.

***

## Handle rate-limit errors

The request that exceeds either limit returns **HTTP 429 Too Many Requests**. The response includes a `Retry-After` header containing the number of seconds until the breached fixed window expires.

When handling a request rate limit:

* Wait at least the number of seconds specified by `Retry-After` before retrying.
* Use bounded exponential backoff and jitter if requests can still collide after the window resets.
* Queue batch workloads and smooth traffic instead of sending large bursts.
* Limit concurrent workers so their combined request rate stays below both limits.
* Reuse uploaded datasets and fitted model IDs when possible instead of repeating upload or fit operations. For repeated predictions against the same training set, consider the [KV cache](/capabilities/kv-cache).

Do not retry rate-limited requests in a tight loop. Requests remain rejected until the current fixed window expires.

The following examples show how the retry delay appears in `tabpfn-client` and raw HTTP responses.

<Tabs>
  <Tab title="tabpfn-client">
    `tabpfn-client` includes the HTTP status and remaining wait time in the exception message. Given a fitted `TabPFNClassifier` or `TabPFNRegressor` called `model`:

    ```python theme={null}
    try:
        predictions = model.predict(X_test)
    except RuntimeError as exc:
        print(f"{type(exc).__name__}: {exc}")
    ```

    Example output—the remaining time and trace ID vary by request:

    ```text theme={null}
    RuntimeError: Fail to call predict: [HTTP 429] Rate limit exceeded: at most 60 predict requests per minute are allowed. Retry in 42s.. Report trace ID: <trace-id>.
    ```

    The high-level client exposes the retry delay in the message, but not the response headers through the `RuntimeError`. Use the REST API directly when your application needs to read `Retry-After` programmatically.
  </Tab>

  <Tab title="REST API">
    The raw response includes the same retry delay in both the JSON message and the `Retry-After` response header:

    ```http theme={null}
    HTTP/1.1 429 Too Many Requests
    Retry-After: 42
    Content-Type: application/json

    {
      "message": "Rate limit exceeded: at most 60 predict requests per minute are allowed. Retry in 42s.",
      "error_code": "USER_ERROR",
      "trace_id": "<trace-id>"
    }
    ```

    With `httpx`, inspect the header before handling other HTTP errors:

    ```python theme={null}
    import httpx

    response = httpx.post(
        f"{BASE}/tabpfn/predict",
        headers=HEADERS,
        json=predict_payload,
    )

    if response.status_code == 429:
        retry_after = int(response.headers["Retry-After"])
        error = response.json()
        print(error["message"])
        print(f"Retry-After header: {retry_after} seconds")
    else:
        response.raise_for_status()
    ```

    Example output:

    ```text theme={null}
    Rate limit exceeded: at most 60 predict requests per minute are allowed. Retry in 42s.
    Retry-After header: 42 seconds
    ```

    See the [REST API quickstart](/api-reference/getting-started) for a complete `predict_payload` example.
  </Tab>
</Tabs>

***

## Higher limits

If the defaults do not support your workload, submit a limit increase request through [Usage](https://ux.priorlabs.ai/account/usage) form in our platform.

***

<CardGroup cols={2}>
  <Card title="API metering" icon="gauge" href="/api-reference/metering">
    Token budgets, usage pools, and thinking fit quotas.
  </Card>

  <Card title="REST quickstart" icon="rocket" href="/api-reference/getting-started">
    Authenticate, upload data, fit a model, and run predictions.
  </Card>

  <Card title="Thinking mode" icon="brain" href="/capabilities/thinking-mode">
    Configure fit-time optimization and understand thinking parameters.
  </Card>

  <Card title="Security" icon="shield" href="/api-reference/security">
    Encryption, data isolation, and access controls.
  </Card>
</CardGroup>
