---
title: "限流"
description: "pirouter 按部署的每分钟配额限流，不按 API key，也不按工作区：配额用满返回 429 rate_limited 和 Retry-After，等到下一个整分钟再发；provider 自己的 429 已经过故障切换才到你手里。"
canonical: "https://pirouter.ai/zh/docs/api/rate-limits"
last-updated: "2026-10-17"
lang: "zh"
source: "content/docs/zh/api/rate-limits.mdx"
---

# 限流

pirouter 按部署的每分钟配额限流，不按 API key，也不按工作区：配额用满返回 429 rate_limited 和 Retry-After，等到下一个整分钟再发；provider 自己的 429 已经过故障切换才到你手里。

pirouter 的限流按部署计，不按 key，也不按工作区。每个部署有每分钟请求数（RPM）和每分钟 token 数（TPM）两项配额；这次请求被选中的部署用满了配额，就返回 `429` `rate_limited`，带上 `Retry-After`。换 key 不能绕开限流。

## 两种 429

你可能收到两种 `429`，处理办法不同：

| 对比项             | pirouter 限流               | provider 限流                     |
| --------------- | ------------------------- | ------------------------------- |
| 谁返回的            | pirouter 网关               | provider，经 pirouter 原样转发        |
| `error.code`    | `rate_limited`            | provider 自己的错误体，没有这个码           |
| `X-Pi-Provider` | 不带                        | 带                               |
| `Retry-After`   | 一定带，1 到 60 秒              | provider 给了才有                   |
| 是否故障切换          | 不切换：请求没有转发，不计费            | 已经切换过：同一模型的其他 provider 都试过了，都失败 |
| 你该做什么           | 等 `Retry-After` 秒，或者换一个模型 | 按 `Retry-After`（有的话）或逐步加长的间隔重试  |

> **提示：** 看 `error.code` 是不是 `rate_limited`，或者看响应有没有 `X-Pi-Provider`，就能分清是哪一种。pirouter 配额的 `429` 不会触发故障切换；provider 返回的 `429` 会。

## 规则

- **按部署计**。同一个模型可能有几个部署，每个部署各有自己的配额。
- **只有 RPM 和 TPM 两项**。两项都是按部署设定的分钟配额。

* **按自然分钟计**。计数在 UTC 的整分钟清零，不是滑动窗口。

- **RPM 在放行时计数，TPM 在请求结束后计数**。被拒绝的请求也计入当分钟的请求数。token 数在请求结束后按实际的输入加输出累加；当分钟的累计达到上限后，下一个请求被拒绝。所以一个大请求可以让当分钟的用量超过上限。

* **只检查被选中的那个部署**。pirouter 先按[路由规则](https://pirouter.ai/zh/docs/guides/routing.md)选出一个部署，再检查它的配额。它用满了就直接返回 `429`，不会改去同一模型的其他部署。

例如一个部署的 RPM 是 60：这一分钟里第 61 个请求返回 `429`，`Retry-After` 是到下一个整分钟的秒数；下一个整分钟开始后计数清零，请求照常放行。

## `rate_limited` 的响应

pirouter 限流时返回 `429`，`error.type` 是 `rate_limit_error`，`error.code` 是 `rate_limited`。代码里按 `error.code` 判断，不要匹配 `error.message` 的文字。

响应带 `Retry-After` 响应头，值是到下一个整分钟的秒数，在 1 到 60 之间。浏览器里的代码也能读到它。

这个响应由网关直接返回，只带 `X-Pi-Trace-Id` 和 CORS 头，不带 `X-Pi-Provider`。请求没有转发给任何 provider，也不扣费：配额检查在预留余额之前。

控制台 **日志** 里，这类请求的状态是 **触发限流**。

## provider 返回的 429

provider 自己限流时，pirouter 先切换到同一模型的其他 provider，再按请求里的 `models` 做[模型回退](https://pirouter.ai/zh/docs/guides/fallbacks.md)，这些都不会让你看到。只有所有候选都失败、而且最后一次仍是 provider 的 `429` 时，你才会收到它：状态码和响应体是 provider 的，带 `X-Pi-Provider`，provider 给的 `Retry-After` 原样转发。

## 和模型回退的关系

- **pirouter 的限流不触发模型回退**。请求一开始就被配额拒绝时，pirouter 不会改用 `models` 里的下一个模型，直接返回 `429`。想立刻得到回复，自己换一个模型发。
- **回退途中被限流，整条回退链结束**。前一次尝试失败、下一个候选又被配额拒绝时，返回的是 `429` `rate_limited` 和 `Retry-After`，不是前一次尝试的错误。

一个请求在所有模型上加起来最多尝试 5 次。

## 重试建议

| 你收到的                                                  | 怎么做                                                          |
| ----------------------------------------------------- | ------------------------------------------------------------ |
| `429` `rate_limited`                                  | 等 `Retry-After` 秒再发，减少同时在途的请求。换 key 没有用                      |
| provider 的 `429`（带 `X-Pi-Provider`）                   | pirouter 已经切换过 provider。有 `Retry-After` 就按它等，没有就逐步加长间隔重试     |
| `402`                                                 | 不要重试，先[充值](https://pirouter.ai/zh/docs/guides/billing.md#充值) |
| `500`、`502`、`503`、`504`，或 `200` 里的 `upstream_timeout` | 逐步加长间隔重试，间隔以秒计                                               |

OpenAI 和 Anthropic 的官方 SDK 默认会自动重试 `429`，并读取 `Retry-After`。这是 SDK 自己的行为，重试次数在 SDK 里设置。

其他错误要不要重试，见[哪些错误可以重试](https://pirouter.ai/zh/docs/api/errors.md#哪些错误可以重试)。

## 目前没有的能力

- **按 key 或按工作区的限流**。
- **剩余额度的响应头**。响应里没有 `x-ratelimit-*` 一类的头，看不到当分钟还剩多少配额。
- **并发数上限**。配额只按每分钟的请求数和 token 数计。

## 下一步

- [模型回退](https://pirouter.ai/zh/docs/guides/fallbacks.md): 请求的模型不可用时换到下一个模型。
- [请求与响应头](https://pirouter.ai/zh/docs/api/headers.md): 每个响应头的含义和出现条件。
