Một 429 từ OpenAI nghĩa là bạn đã vượt qua một trong năm ngưỡng — và việc đầu tiên là xác định ngưỡng nào, vì cách khắc phục đi theo các hướng trái ngược. Trang này giải thích mỗi giới hạn đo lường gì, cách đọc câu trả lời trực tiếp từ header phản hồi, logic thử lại thực sự ngăn lỗi và cần làm gì khi backoff đúng cách vẫn chưa đủ.
Đã xác minh 30 tháng 9, 2026 dựa trên tài liệu giới hạn tốc độ của OpenAI.
Năm giới hạn, bất kỳ giới hạn nào cũng có thể kích hoạt lỗi
| Chỉ số | Đo lường | Thường gây vấn đề khi |
|---|---|---|
| RPM | Yêu cầu mỗi phút | Nhiều lệnh gọi nhỏ — phân loại, embedding, vòng lặp agent |
| TPM | Token mỗi phút | Ít lệnh gọi lớn — RAG với ngữ cảnh truy xuất lớn, tài liệu dài |
| RPD | Yêu cầu mỗi ngày | Free và các cấp thấp; job batch dùng hết hạn ngạch hàng ngày |
| TPD | Token mỗi ngày | Tương tự, được đo bằng token |
| IPM | Hình ảnh mỗi phút | Workload tạo hình ảnh |
Giới hạn nào cạn trước sẽ kích hoạt lỗi, vì vậy “chúng tôi còn cách xa giới hạn token” không phải lý do để loại trừ giới hạn tốc độ — bạn có thể còn xa TPM nhưng đã chạm đúng RPM. Giới hạn áp dụng theo tổ chức và model, không theo khóa: tạo thêm khóa không tạo thêm hạn ngạch.
Lỗi 429 trông như thế nào
HTTP/1.1 429 Too Many Requests
retry-after: 12
x-ratelimit-limit-requests: 500
x-ratelimit-remaining-requests: 0
x-ratelimit-reset-requests: 12s
x-ratelimit-limit-tokens: 200000
x-ratelimit-remaining-tokens: 143820
x-ratelimit-reset-tokens: 17s
{
"error": {
"message": "Rate limit reached for gpt-5.4 in organization org-... on requests per min (RPM).",
"type": "requests",
"code": "rate_limit_exceeded"
}
}Mọi thông tin cần thiết đều nằm trong phản hồi đó. Nội dung thông báo nêu chiều bị chạm (“requests per min (RPM)”), còn các header cho biết ngưỡng chính xác, phần còn lại và thời điểm phục hồi.
| Tiêu đề | Ý nghĩa |
|---|---|
retry-after | Số giây tối thiểu cần chờ trước khi thử lại |
x-ratelimit-limit-requests | Số yêu cầu tối đa được phép trước khi cạn giới hạn |
x-ratelimit-remaining-requests | Số yêu cầu còn lại trước khi cạn giới hạn |
x-ratelimit-limit-tokens | Số token tối đa được phép |
x-ratelimit-remaining-tokens | Số token còn lại |
x-ratelimit-reset-requests / -reset-tokens | Thời gian đến khi từng bộ đếm được đặt lại — chúng được đặt lại độc lập |
Các cấp độ sử dụng
Các ngưỡng của bạn được xác định bởi cấp độ sử dụng, và OpenAI tự động nâng cấp khi tổng chi tiêu lũy kế tăng lên:
| Cấp | Điều kiện | Giới hạn sử dụng hàng tháng |
|---|---|---|
| Miễn phí | Người dùng ở khu vực được phép | $100 / tháng |
| Cấp 1 | Đã thanh toán $5 | $100 / tháng |
| Cấp 2 | Đã thanh toán $50 | $500 / tháng |
| Cấp 3 | Đã thanh toán $100 | $1.000 / tháng |
| Cấp 4 | Đã thanh toán $250 | $5.000 / tháng |
| Cấp 5 | Đã thanh toán $1.000 | $200.000 / tháng |
Cố ý không sao chép các con số RPM và TPM theo từng model tại đây. Chúng khác nhau theo model, thay đổi khi model được phát hành và có thể được điều chỉnh theo từng tài khoản — vì vậy mọi bảng được đăng trên trang bên thứ ba đều chỉ là phỏng đoán kèm một mốc thời gian. Hai nguồn có thẩm quyền cho tài khoản của bạn là trang giới hạn trong dashboard OpenAI và các header x-ratelimit-* trên mọi phản hồi bạn đã nhận. Hãy đọc các header.
Cách khắc phục: tuân thủ Retry-After, sau đó thêm jitter
Khuyến nghị được OpenAI ghi nhận là exponential backoff với jitter, tuân theo Retry-After khi phản hồi có header này. Cả hai phần đều quan trọng. Không có header, bạn có thể thử lại quá sớm; không có jitter, mọi client gặp lỗi cùng thời điểm sẽ thử lại cùng thời điểm và cùng thất bại — một đàn client đồng loạt khiến một giây tồi tệ biến thành cả phút tồi tệ.
import random, time
import openai
client = openai.OpenAI()
def call_with_backoff(fn, *, max_attempts=6, base=0.5, cap=30.0):
"""Retry 429s: honour Retry-After when present, jittered backoff otherwise."""
for attempt in range(max_attempts):
try:
return fn()
except openai.RateLimitError as err:
if attempt == max_attempts - 1:
raise
# The server's own answer beats any formula you invent.
retry_after = (err.response.headers or {}).get("retry-after")
if retry_after:
delay = float(retry_after)
else:
# Full jitter: sleep a random point in [0, 2^n * base], capped.
# Without the randomness every client that failed at the same
# instant retries at the same instant and fails again together.
delay = random.uniform(0, min(cap, base * 2**attempt))
time.sleep(delay)
resp = call_with_backoff(lambda: client.responses.create(
model="gpt-5.4",
input="Summarise this changelog in three bullets.",
))Cùng dạng trong TypeScript:
import OpenAI from "openai";
const client = new OpenAI();
const sleep = (ms: number) => new Promise((r) => setTimeout(r, ms));
export async function callWithBackoff<T>(
fn: () => Promise<T>,
{ maxAttempts = 6, baseMs = 500, capMs = 30_000 } = {},
): Promise<T> {
for (let attempt = 0; ; attempt++) {
try {
return await fn();
} catch (err) {
const status = (err as { status?: number }).status;
if (status !== 429 || attempt === maxAttempts - 1) throw err;
const retryAfter = (err as { headers?: Headers }).headers?.get("retry-after");
const delay = retryAfter
? Number(retryAfter) * 1000
: Math.random() * Math.min(capMs, baseMs * 2 ** attempt);
await sleep(delay);
}
}
}
const resp = await callWithBackoff(() =>
client.responses.create({ model: "gpt-5.4", input: "Hello" }),
);Các SDK chính thức đã tự động thử lại lỗi 429, vì vậy hầu hết ứng dụng chỉ cần đoạn này khi bọc các lệnh gọi bằng HTTP client riêng hoặc khi muốn hành vi khác — ngưỡng chờ dài hơn cho công việc nền, hoặc thất bại ngay lập tức với yêu cầu hướng tới người dùng khi chờ 12 giây còn tệ hơn lỗi.
Giám sát trước khi sự cố xảy ra
Các bộ đếm có trong mọi phản hồi, không chỉ phản hồi lỗi. Ghi log các giá trị còn lại biến giới hạn tốc độ từ một sự cố thành một đồng hồ đo — bạn có thể thấy khoảng trống giảm dần nhiều ngày trước khi một lần ra mắt dùng hết nó.
# Log the remaining counters on every response, not just on failures.
# By the time you see a 429 the useful signal is already an hour old.
resp = client.responses.with_raw_response.create(model="gpt-5.4", input="…")
h = resp.headers
log.info(
"openai_quota model=%s req_left=%s tok_left=%s reset_req=%s reset_tok=%s",
"gpt-5.4",
h.get("x-ratelimit-remaining-requests"),
h.get("x-ratelimit-remaining-tokens"),
h.get("x-ratelimit-reset-requests"),
h.get("x-ratelimit-reset-tokens"),
)
parsed = resp.parse() # the normal response objectHai thói quen đáng áp dụng cùng với việc đó: cảnh báo khi x-ratelimit-remaining-tokens giảm xuống dưới một phần nào đó của giới hạn thay vì cảnh báo theo số lượng 429, và thêm jitter vào lịch chạy, không chỉ vào các lần thử lại. Một cron kích hoạt mọi thứ tại :00 tự tạo ra đợt tăng đột biến của mình.
Khi backoff không phải là câu trả lời
Backoff đúng cách khắc phục các đợt tăng đột biến. Nó không làm gì được với nhu cầu ổn định vượt quá ngưỡng của bạn — trong trường hợp đó, việc thử lại chỉ dời thời điểm thất bại. Các cách khắc phục mang tính cấu trúc, xấp xỉ theo mức độ công sức:
- Giới hạn output. Token suy luận được tính phí và tính vào output, vì vậy việc tạo không giới hạn là cách nhanh nhất làm cạn TPM.
- Rút gọn ngữ cảnh truy xuất. Với ngưỡng TPM, giảm một nửa số chunk truy xuất sẽ miễn phí nhân đôi thông lượng.
- Chọn model phù hợp. Một bước phân loại không cần model hàng đầu, và các model nhỏ có ngân sách riêng.
- Tách workload. Job batch và lưu lượng nhạy cảm về độ trễ tranh nhau một ngưỡng cấp tổ chức là dạng phổ biến nhất của vấn đề này do chính người dùng tạo ra.
- Nâng cấp cấp độ. Các cấp độ thay đổi theo chi tiêu lũy kế, vì vậy việc này thường đã tự diễn ra.
Phân bổ tải trên các họ model
Mục cuối trong danh sách là nơi gateway phát huy giá trị. Kunavo cung cấp API tương thích với OpenAI — cùng SDK, cùng dạng lệnh gọi, một khóa — trên nhiều họ model, vì vậy chuyển workload khỏi một ngưỡng đã bão hòa chỉ là thay đổi chuỗi model thay vì tích hợp lần hai:
from openai import OpenAI
client = OpenAI(
api_key="sk-kn-...",
base_url="https://api.kunavo.com/v1",
)
# Same SDK, same call shape — the model string chooses the family.
client.chat.completions.create(
model="gpt-5-6-terra", # or claude-sonnet-5, claude-haiku-4-5, …
messages=[{"role": "user", "content": "Hello"}],
)Cụ thể: job batch tóm tắt từng cạnh tranh với lưu lượng production của bạn có thể chạy trên claude-haiku-4-5 với mức $0,70 / $3,50 trên mỗi 1M, trong khi đường dẫn nhạy cảm về độ trễ vẫn chạy trên gpt-5-6-terra ($0,70 / $4,20) hoặc claude-sonnet-5 ($1,40 / $7,00). Khác họ, khác hàng đợi.
Cần hiểu rõ việc này làm được và không làm được gì. Nó loại bỏ nút thắt một tài khoản — một model và cho bạn một nơi để chuyển dự phòng. Nó không tạo ra năng lực: nếu tổng lưu lượng thực sự vượt quá mức bất kỳ cấp độ nào cho phép, câu trả lời vẫn là nâng cấp cấp độ hoặc giảm công việc. Giá của mọi model có trên trang giá, còn hướng dẫn tương đương cho giới hạn của Anthropic có trong Claude API 429 rate_limit_error.
Câu hỏi thường gặp
Giới hạn tốc độ API của OpenAI là gì?
OpenAI đo đồng thời năm chiều — RPM (yêu cầu mỗi phút), TPM (token mỗi phút), RPD (yêu cầu mỗi ngày), TPD (token mỗi ngày) và IPM (hình ảnh mỗi phút) — đồng thời trả về HTTP 429 ngay khi bất kỳ giới hạn nào bị vượt qua. Các ngưỡng thực tế phụ thuộc vào cấp độ sử dụng và model cụ thể của bạn, vì vậy các con số có thẩm quyền cho tài khoản của bạn nằm trên trang giới hạn của tổ chức trong dashboard OpenAI và trong các header x-ratelimit-* của mọi phản hồi, không nằm trong bất kỳ bảng công khai nào.
Các cấp độ sử dụng OpenAI là gì?
Tính đến 30 tháng 9, 2026 OpenAI ghi nhận sáu cấp độ, mỗi cấp được mở khóa theo tổng chi tiêu lũy kế và mỗi cấp có giới hạn sử dụng hàng tháng: Miễn phí (khả dụng tại các khu vực được hỗ trợ, $100/tháng), Cấp 1 sau khi thanh toán $5 ($100/tháng), Cấp 2 sau khi thanh toán $50 ($500/tháng), Cấp 3 sau khi thanh toán $100 ($1.000/tháng), Cấp 4 sau khi thanh toán $250 ($5.000/tháng) và Cấp 5 sau khi thanh toán $1.000 ($200.000/tháng). Cấp độ được nâng tự động khi chi tiêu tích lũy.
Làm cách nào sửa lỗi 429 rate_limit_exceeded từ OpenAI?
Tuân thủ header Retry-After khi phản hồi có header này; nếu không, hãy thử lại với exponential backoff cộng jitter ngẫu nhiên — đây là khuyến nghị được OpenAI ghi nhận. Các SDK chính thức đã tự động thử lại; HTTP client tự xây dựng phải triển khai cơ chế này. Nếu lỗi 429 vẫn tiếp diễn sau khi backoff đúng cách, bạn thực sự đã vượt hạn ngạch thay vì chỉ tạo đột biến lưu lượng, và cách khắc phục mang tính cấu trúc: chia batch nhỏ hơn, giới hạn token output tối đa, phân bổ các job theo lịch trong cả phút, hoặc chuyển lên cấp độ cao hơn.
Tôi thực sự đã chạm giới hạn tốc độ nào?
Đọc các header. x-ratelimit-remaining-requests bằng 0 nghĩa là bạn đã chạm giới hạn yêu cầu; x-ratelimit-remaining-tokens bằng 0 nghĩa là giới hạn token. Hai giới hạn được đặt lại độc lập — x-ratelimit-reset-requests và x-ratelimit-reset-tokens cho biết thời điểm mỗi giới hạn phục hồi. Nội dung thông báo cũng nêu chiều bị chạm. Đoán giữa hai giới hạn chỉ làm mất thời gian, vì cách khắc phục trái ngược nhau: giới hạn yêu cầu cần xếp hàng, còn giới hạn token cần prompt nhỏ hơn.
Giới hạn tốc độ áp dụng theo khóa hay theo tổ chức?
Theo tổ chức và model, không theo khóa. Tạo thêm API key không tạo thêm hạn ngạch, đó là lý do workload production bận rộn và job batch trong cùng tổ chức tranh nhau cùng một ngưỡng — và cũng là lý do việc tách chúng quan trọng hơn việc thêm khóa.
Gateway có thể giúp xử lý giới hạn tốc độ OpenAI không?
Gateway giúp xử lý trường hợp ngưỡng theo model của một tài khoản là nút thắt, vì gateway cho phép chuyển workload sang một họ model khác bằng cùng khóa và cùng SDK — job batch tóm tắt không cần xếp chung hàng với lưu lượng nhạy cảm về độ trễ. Gateway không tạo ra năng lực từ hư không: nếu tổng lưu lượng thực sự cao hơn mức bất kỳ cấp độ đơn lẻ nào cho phép, câu trả lời vẫn là nâng cấp cấp độ hoặc giảm khối lượng công việc.
Tại sao tài khoản hoàn toàn mới của tôi đã bị giới hạn tốc độ?
Tài khoản Free và Tier 1 có giới hạn hàng ngày (RPD và TPD) mà các cấp cao hơn không có, vì vậy một script thử nghiệm vừa phải cũng có thể dùng hết hạn mức trong ngày vào buổi chiều. Tier 1 được mở khóa khi đạt $5 thanh toán lũy kế.
Lỗi 429 có khiến tôi mất phí không?
Không — yêu cầu bị từ chối không được xử lý và không bị tính phí. Điều bạn mất là độ trễ và bất kỳ tác động nào mà logic thử lại của bạn tạo ra từ độ trễ đó.
Thêm API key có tăng thông lượng không?
Không. Giới hạn áp dụng theo tổ chức và model. Khóa bổ sung hữu ích cho việc quy thuộc và thu hồi, không hữu ích cho năng lực.
Tôi nên bắt lỗi 429 hay để SDK xử lý?
Hãy để SDK xử lý trường hợp thông thường, và tự bắt lỗi khi mặc định không phù hợp với bạn: yêu cầu hướng tới người dùng cần thất bại nhanh, hoặc job nền có thể chấp nhận ngưỡng chờ dài hơn nhiều so với mặc định.
Còn các lỗi 429 thực chất là hết hạn ngạch thì sao?
Giới hạn sử dụng hàng tháng bị cạn cũng xuất hiện dưới dạng 429, và không có mức backoff nào xóa được lỗi đó — nội dung thông báo phân biệt hai trường hợp. Nếu các bộ đếm trong header vẫn ổn nhưng yêu cầu vẫn bị từ chối, hãy kiểm tra thanh toán trước khi chỉnh code thử lại.