---
title: Rate Limits
description: Understand shared member rate limits, read rate-limit state in REST headers and WebSocket responses, and throttle before you are rejected.
---

Request capacity is shared by the member. Every user, account, API key, and connection under that member draws from the same `read`, `write`, and `cancel` buckets, so creating another API key or opening another connection does not increase capacity.

Authenticated REST requests and WebSocket commands both charge these buckets. Some REST operations accept but do not require authentication: an authenticated request charges the member's `read` bucket like any other, while an unauthenticated request shares a separate per-client limit and carries no bucket state. Streaming market data never carries bucket state.

A REST request rejected by a rate limit is not saved as an operation's result. Wait for the advised interval, then retry the same request with a new timestamp and signature, reusing any [idempotency key](/reference/idempotency) it carried. When a WebSocket command receives an `error` frame with `code: rate_limit_exceeded`, it is not saved as an operation's result; wait for `retry_after_ms`, then send a new command with a fresh `id` and the same `params`. The session was signed at connect, so do not add a per-message signature. For a missing or otherwise unresolved response, follow [Asynchronous Writes](/reference/asynchronous-writes) before retrying.



## Read Your Remaining Capacity

**REST**

Responses for requests that use a bucket include `RateLimit-Policy` and `RateLimit` headers for that bucket:

```http
RateLimit-Policy: "read";q=30;w=2
RateLimit: "read";r=12;t=1
```

- `q` is the bucket's token capacity.
- `w` is the number of seconds required to refill an empty bucket.
- `r` is the number of tokens remaining after the request.
- `t` is the number of seconds until the bucket is full.

Use `r` to slow requests before receiving a `429`. These headers are absent when a request does not use a bucket, including an idempotent replay and a `503`.

The field format follows the IETF's [RateLimit header fields for HTTP draft](https://datatracker.ietf.org/doc/draft-ietf-httpapi-ratelimit-headers/). HTTP `429 Too Many Requests` and `Retry-After` behavior are defined in [RFC 6585](https://www.rfc-editor.org/rfc/rfc6585.html#section-4).

**WebSocket**

Each command charges the bucket and weight published for it in the [WebSocket API](/api-reference/websocket). A subscribe command costs more as it names more tickers. The response to a charged command carries a `rate_limit` object with the state left by that decision:

| Field | Meaning |
| --- | --- |
| `bucket` | The bucket consulted: `read`, `write`, or `cancel`. |
| `capacity` | The bucket's token capacity. |
| `refill_tokens_per_minute` | Tokens restored per minute. |
| `remaining` | Tokens left after this command. |
| `full_after_ms` | Milliseconds until the bucket is full if nothing else is admitted. |

Use `remaining` to pace commands. A response that spent no tokens, such as an exact duplicate subscribe, omits `rate_limit`. Streaming market data never carries it.

## Handle a Rejection

**REST**

When a REST request exhausts its bucket, the exchange returns:

- `429 Too Many Requests`;
- `Retry-After` in integer seconds;
- `Cache-Control: no-store`; and
- Problem Details whose `type` is `urn:udx:problem:member-rate-limit-exceeded` when the member's bucket was exhausted, or `urn:udx:problem:unauthenticated-rate-limit-exceeded` when an unauthenticated request exhausted the public per-client limit.

A `503 Service Unavailable` with `type: urn:udx:problem:request-admission-unavailable` means UDX could not safely evaluate whether to admit the request; it does not mean the member exhausted its capacity. Retry it with bounded exponential backoff and jitter. Do not use the human-readable `detail` field to decide how to recover.

**WebSocket**

A rejected command answers with an `error` frame correlated by your command `id`:

- `rate_limit_exceeded` carries `retry_after_ms` and the `rate_limit` state. Wait at least that long before sending the command again.
- `capacity_exceeded` means a standing resource is at its limit: in-flight commands, active subscriptions, or market data streams, at connection, member, or process scope. Release resources rather than retrying.
- `admission_unavailable` means UDX could not evaluate the command. Retry with bounded backoff.

## Check Current Limits

[`GET /rate_limit_profile`](/api-reference/rest/rate-limits/get-rate-limit-profile) returns the member's bucket capacity, refill rate, and cost per request.
