Nhà cung cấp giới hạn theo hai chiều: số request mỗi phút (RPM) và số token mỗi phút (TPM). Vượt chiều nào cũng nhận 429, và trong ứng dụng LLM thì TPM thường chạm trần trước vì mỗi request nuốt hàng nghìn token.
Ba tầng cần có:
1. Giới hạn theo người dùng ở cửa vào. Token bucket theo user_id trong Redis, trả 429 kèm Retry-After ngay. Đây là tầng chặn một người dùng chiếm hết dung lượng của cả hệ thống.
2. Hàng đợi tập trung phía sau. Mọi lời gọi provider đi qua một hàng đợi có giới hạn số job chạy song song, đặt dưới mức trần của tài khoản. Ước lượng token của request trước khi cho chạy để bám theo TPM, không chỉ đếm số request.
3. Tôn trọng tín hiệu của provider. Đọc header phần dung lượng còn lại và retry-after để giảm nhịp chủ động thay vì cứ đâm vào tường rồi mới lùi.
Phân biệt theo loại việc: yêu cầu tương tác (người dùng đang ngồi chờ) phải được ưu tiên; việc nền như tóm tắt hàng loạt, tạo embedding thì đẩy sang hàng đợi độ ưu tiên thấp, hoặc dùng batch API rẻ hơn nếu chấp nhận chậm.
UX khi phải xếp hàng: cho biết vị trí trong hàng đợi và thời gian ước tính. Nếu hàng đợi quá dài, từ chối sớm và hiển thị thông báo rõ ràng — vẫn tốt hơn là để người dùng nhìn spinner rồi timeout.