คุณส่งฟังก์ชันที่เรียกใช้ GPT API ขึ้น production แล้วเจอ 429 Too Many Requests หลังผู้ใช้ชุดแรกเริ่มใช้งาน สิ่งแรกที่ต้องแยกให้ออกคือคุณชนขีดจำกัดแบบไหน: requests per minute (RPM), tokens per minute (TPM), daily caps หรือขีดจำกัดเฉพาะโมเดล/เอนด์พอยต์
💡 บทความนี้สรุปวิธีตรวจสอบ rate limit ของ GPT API จาก response headers, อ่าน error body ของ
429, และทดสอบ burst/concurrency ด้วย Apidog เพื่อให้ทีมมีขั้นตอนซ้ำได้สำหรับ debug ปัญหา rate limit ก่อน deploy จริง
หากคุณเคยใช้ OpenAI API มาก่อน จะรู้ว่า rate limit ไม่ได้มีแค่ตัวเลขเดียว โมเดลข้อความ, รูปภาพ, embeddings, audio และ batch endpoint มีวิธีนับและข้อจำกัดต่างกัน ระดับการใช้งานของบัญชีก็เปลี่ยนได้ตามยอดใช้จ่ายและสถานะ billing ดังนั้นวิธีที่ปลอดภัยที่สุดคืออ่านค่าจริงจาก API response แล้วทดสอบโหลดขนาดเล็กด้วยเครื่องมืออย่าง Apidog
สี่ขีดจำกัดที่ต้องตรวจสอบจริง
OpenAI ใช้ rate limit หลายมิติกับ API key แต่สำหรับแอป production ส่วนใหญ่ ให้เริ่มจาก 4 กลุ่มนี้:
- RPM — requests per minute หรือจำนวนคำขอต่อนาที
- TPM — tokens per minute หรือจำนวน input/output tokens ต่อนาที
- RPD — requests per day มักพบใน free tier หรือ Tier 1 บางกรณี
- IPM / TPD / batch queue limits — ขีดจำกัดเฉพาะสำหรับ image, audio, embeddings และ Batch API
เมื่อ request ถูกปฏิเสธ API จะตอบกลับ HTTP 429 พร้อม body ประมาณนี้:
{
"error": {
"message": "Rate limit reached for gpt-5.5 in organization org-abc on tokens per min (TPM): Limit 30000, Used 28432, Requested 3120.",
"type": "tokens",
"param": null,
"code": "rate_limit_exceeded"
}
}
จุดที่ต้องอ่านคือ message, type, และ code เพราะจะบอกว่าคุณชนขีดจำกัดแบบใด เช่น:
-
tokens= มักเกี่ยวกับ TPM -
requests= มักเกี่ยวกับ RPM -
tokens_usage_based= เกี่ยวกับการใช้ token/usage limit
429 แต่ละครั้งไม่ได้แก้เหมือนกัน ถ้าชน RPM ต้องลดจำนวน request ต่อเวลา แต่ถ้าชน TPM ต้องลด token, ตัด context, ลด max_tokens, หรือแบ่งงานออกเป็นหลาย request
อ่านเพิ่มเติมเกี่ยวกับ HTTP 429 ได้จาก เอกสาร MDN 429, RFC 6585 และ หน้า rate limits อย่างเป็นทางการของ OpenAI
ระดับชั้นของ OpenAI ทำงานอย่างไร
API key ของคุณอยู่ภายใต้ usage tier ขององค์กร OpenAI tier จะกำหนดตัวเลขจริงของ RPM/TPM และมักขึ้นอยู่กับ:
- ยอดใช้จ่ายสะสมของบัญชี
- ระยะเวลาหลังจากชำระเงินครั้งแรก
ตัวอย่างภาพรวมคร่าว ๆ สำหรับ text models:
| ระดับชั้น | เกณฑ์การใช้จ่าย | เกณฑ์การรอ | RPM ข้อความ | TPM ข้อความ |
|---|---|---|---|---|
| ฟรี | ไม่มี | ไม่มี | 3 | 40k |
| 1 | ชำระแล้ว $5 | ไม่มี | 500 | 30k–200k ขึ้นอยู่กับโมเดล |
| 2 | ชำระแล้ว $50 | 7 วัน | 5,000 | 450k |
| 3 | ชำระแล้ว $100 | 7 วัน | 5,000 | 1M |
| 4 | ชำระแล้ว $250 | 14 วัน | 10,000 | 2M |
| 5 | ชำระแล้ว $1,000 | 30 วัน | 10,000 | 2M+ |
ตัวเลขนี้เป็นตัวอย่างเท่านั้น ขีดจำกัดจริงเปลี่ยนได้ตามเวลา โมเดล และสถานะบัญชี ให้ยืนยันจาก dashboard หรือ response headers ทุกครั้งก่อน sizing workload
ผลกระทบที่ควรรู้:
การเลื่อน tier เกิดอัตโนมัติ
เมื่อถึงเกณฑ์ยอดใช้จ่ายและเวลารอ request ถัดไปจะใช้ limit ใหม่โดยไม่ต้อง migrateบัญชีอาจถูกลด tier ได้
หาก billing มีปัญหา หรือบัญชีไม่ active เป็นเวลานาน ควรทดสอบใหม่หลังมีการเปลี่ยนแปลง billing
หากต้องการเทียบแนวคิด rate limit กับผู้ให้บริการอื่น ดูเพิ่มเติมได้ที่ คำอธิบายอัตราการจำกัดของผู้ใช้ OpenAI API, คู่มืออัตราการจำกัด Claude API, และ คู่มืออัตราการจำกัด Grok-3 API
อ่าน limit จริงจาก response headers
คุณไม่จำเป็นต้องเดาจาก dashboard อย่างเดียว ให้ส่ง request จริงหนึ่งครั้ง แล้วดู headers เหล่านี้:
-
x-ratelimit-limit-requests— RPM limit ของ endpoint/model นี้ -
x-ratelimit-remaining-requests— จำนวน request ที่เหลือในรอบเวลาปัจจุบัน -
x-ratelimit-limit-tokens— TPM limit -
x-ratelimit-remaining-tokens— token ที่เหลือในรอบเวลาปัจจุบัน -
x-ratelimit-reset-requests— เวลาก่อน request quota จะ reset -
x-ratelimit-reset-tokens— เวลาก่อน token quota จะ reset
ตัวอย่างค่า reset อาจเป็น 6s, 1m30s หรือรูปแบบเวลาอื่นที่ API ส่งกลับมา
ขั้นตอนที่ 1: สร้าง GPT request ใน Apidog
เปิด Apidog แล้วสร้าง request ใหม่
POST https://api.openai.com/v1/chat/completions
ตั้งค่า headers:
| Key | Value |
|---|---|
Authorization |
Bearer {{OPENAI_API_KEY}} |
Content-Type |
application/json |
ใช้ environment variable ของ Apidog เพื่อไม่ต้องฝัง API key ลงใน request โดยตรง:
OPENAI_API_KEY=sk-...
จากนั้นตั้งค่า body เป็น JSON:
{
"model": "gpt-5.5",
"messages": [
{
"role": "user",
"content": "ping"
}
],
"max_tokens": 10
}
กด Send แล้วเปิดแท็บ Headers ใน response panel จากนั้นจดค่า x-ratelimit-* ไว้เป็น baseline
หากต้องการดูขั้นตอนการตั้งค่า request แบบละเอียด รวมถึง auth, streaming และ tool calls อ่านต่อได้ที่ คู่มือวิธีทดสอบ ChatGPT API ด้วย Apidog
ขั้นตอนที่ 2: ยืนยัน RPM ด้วย burst test
การส่ง request เดียวช่วยให้เห็น limit แต่ยังไม่พิสูจน์ behavior ตอนชน limit ให้ทำ burst test ขนาดเล็กใน Apidog:
- เปิด request ที่บันทึกไว้
- คลิก dropdown ข้างปุ่ม Send
- เลือก Run in Test Scenario
- ตั้งค่าเช่น:
Iterations: 50
Concurrency: 10
Delay between iterations: 0 ms
ผลลัพธ์ที่ควรดู:
- ถ้าบาง request ได้
429ก่อนจบ scenario แปลว่า burst test ชน limit จริง - ถ้าทั้งหมดสำเร็จ ให้ดูว่า
x-ratelimit-remaining-requestsลดลงตามคาดหรือไม่ - คลิก response ที่เป็น
429แล้วอ่านerror.messageเพื่อดูว่าชนRPM,TPMหรือ daily quota
Apidog Test runner จะเก็บ response แต่ละรายการไว้ ทำให้ sort ตาม status code แล้วเปิดดู 429 ได้ง่าย
อ่านแนวทางแก้ปัญหาเพิ่มเติมได้ที่ คู่มือการเกินอัตราการจำกัด
ขั้นตอนที่ 3: แยก RPM ออกจาก TPM
burst test ด้านบนใช้ payload เล็ก จึงเหมาะกับการทดสอบ RPM หากต้องการทดสอบ TPM ให้ลดจำนวน request แต่เพิ่มขนาด prompt
ตัวอย่าง body สำหรับทดสอบ TPM:
{
"model": "gpt-5.5",
"messages": [
{
"role": "system",
"content": "<3,000 โทเค็นของบริบทที่นี่>"
},
{
"role": "user",
"content": "สรุปข้างต้นเป็นประโยคเดียว"
}
],
"max_tokens": 200
}
ตั้ง scenario ใหม่ เช่น:
Iterations: 20
Concurrency: 5
Delay: 0 ms
ถ้าอยู่ใน tier ที่มี TPM ต่ำ คุณอาจชน token limit ก่อน request limit
วิธีแก้ขึ้นอยู่กับสิ่งที่ชน:
| ชน limit | วิธีแก้หลัก |
|---|---|
| RPM | queue, concurrency limit, batch request, worker pool |
| TPM | ลด context, ตัด system prompt, ลด max_tokens, แบ่ง request, cache context |
ขั้นตอนที่ 4: จำลองผู้ใช้พร้อมกัน
production traffic ไม่ได้เป็น request ขนาดเท่ากันทั้งหมด ควรสร้าง scenario ที่ใกล้เคียง workload จริง เช่น:
- request ขนาดเล็ก
- request ขนาดกลาง
- request ขนาดใหญ่
- delay แบบสุ่มระหว่างรอบ
ใน Apidog คุณสามารถใช้ pre/post script ด้วย JavaScript เพื่อควบคุม scenario ได้ เช่น:
const sizes = ["small", "medium", "large"];
const selected = sizes[Math.floor(Math.random() * sizes.length)];
apidog.variables.set("prompt_size", selected);
ตัวอย่างสิ่งที่ควรวัด:
- status code distribution:
200เทียบกับ429 - latency ของ request ที่สำเร็จ
- latency และ retry behavior ของ request ที่โดน limit
- ค่า
x-ratelimit-remaining-tokensหลังแต่ละ response
เมื่อจบ scenario ให้บันทึก histogram ของ status code ไว้ใน runbook ทีม ครั้งต่อไปที่มีคนถามว่า “เราโดน rate limit หรือเปล่า?” คุณสามารถรัน scenario เดิมแล้วเทียบผลได้ทันที
จะทำอย่างไรเมื่อโดน rate limit
เมื่อยืนยันแล้วว่า limit อยู่ตรงไหน ให้เลือกแนวทางตามปัญหา
1. Backoff และ retry
ทุก GPT API call ควรมี retry พร้อม exponential backoff โดยเฉพาะสำหรับ 429
ตัวอย่าง pseudo-code:
async function callWithRetry(fn, maxRetries = 5) {
for (let attempt = 0; attempt < maxRetries; attempt++) {
try {
return await fn();
} catch (err) {
if (err.status !== 429 || attempt === maxRetries - 1) {
throw err;
}
const reset = err.headers?.["x-ratelimit-reset-tokens"];
const fallbackDelayMs = Math.pow(2, attempt) * 1000;
const delayMs = reset
? parseResetHeaderToMs(reset)
: fallbackDelayMs;
await sleep(delayMs);
}
}
}
ถ้ามี x-ratelimit-reset-tokens หรือ x-ratelimit-reset-requests ให้ใช้ค่านั้นเป็น delay แรก เพราะเป็นค่าที่ API บอกโดยตรงว่าควรรอนานแค่ไหน
2. Queue งาน
ถ้า traffic มาเป็น burst ให้ใส่ request ลง queue แล้วระบายออกด้วย rate ต่ำกว่า limit จริงเล็กน้อย
แนวทางทั่วไป:
allowed_rpm = observed_rpm * 0.8
allowed_tpm = observed_tpm * 0.8
จากนั้นควบคุม worker pool ไม่ให้เกินค่าดังกล่าว
อ่านเพิ่มเติมเกี่ยวกับการ implement rate limiting ได้ที่ วิธีใช้งานการจำกัดอัตรา API และ การใช้งานการจำกัดอัตราใน APIs
3. ใช้ Batch API สำหรับงานที่ไม่ต้องตอบทันที
ถ้างานของคุณรอได้ เช่น:
- enrich ข้อมูลข้ามคืน
- classify เอกสารจำนวนมาก
- regenerate embeddings
- process dataset เป็นรอบ
ให้พิจารณาใช้ Batch API เพื่อลดแรงกดบน synchronous quota สำหรับ user-facing traffic
ถ้าต้องการแยกคำว่า throttling กับ rate limiting ก่อนตัดสินใจ อ่าน throttle vs. rate limit
ข้อผิดพลาด 429 ที่พบบ่อย
1. เกิน requests per minute
ข้อความมักมีลักษณะประมาณ:
Rate limit reached ... on requests per min (RPM)
ความหมาย: โค้ดส่ง API call มากเกินไปในหนึ่งนาที
แนวทางแก้:
- จำกัด concurrency
- อย่า
Promise.all()กับงานจำนวนมากโดยไม่มี limiter - ตั้ง worker pool ตาม RPM จริง
- เพิ่ม queue
2. เกิน tokens per minute
ข้อความมักมีลักษณะประมาณ:
Rate limit reached ... on tokens per min (TPM)
ความหมาย: request ใช้ token รวมมากเกินไป
แนวทางแก้:
- ลด system prompt
- ลดจำนวน context จาก RAG
- ลด
max_tokens - แบ่งเอกสารเป็น chunk
- cache context ที่ใช้ซ้ำได้
3. เกิน quota หรือมีปัญหา billing
ข้อความมักมีลักษณะประมาณ:
You exceeded your current quota, please check your plan and billing details
แม้จะเป็น HTTP 429 แต่สาเหตุอาจไม่ใช่ rate limit แบบ RPM/TPM อาจเป็น:
- ถึง monthly spending limit
- payment method ล้มเหลว
- credit หมด
- billing ยังไม่ active
กรณีนี้ต้องแก้ใน billing dashboard ไม่ใช่ retry ในโค้ด
คำถามที่พบบ่อย
Apidog มีค่าใช้จ่ายในการทดสอบ rate limit ของ GPT หรือไม่?
แผนฟรีเพียงพอสำหรับการส่ง request เดี่ยวและ concurrency test ขนาดเล็ก หากต้องการ load test ใหญ่ขึ้น, team workspace หรือ scheduled runs อาจต้องดูแผนแบบชำระเงินที่ ราคา Apidog
ทดสอบ rate limit โดยไม่ใช้ token จริงได้ไหม?
ได้บางส่วน วิธีที่ถูกที่สุดคือส่ง request เล็กมาก เช่น max_tokens: 1 และ prompt สั้น ๆ เพื่ออ่าน response headers
แต่ถ้าต้องการ burst test หรือ TPM test จริง คุณต้องใช้ token จริง หากต้องการทดสอบ retry logic แบบ offline ให้ใช้ mock server ใน Apidog เพื่อจำลอง 429 โดยไม่ต้องเรียก OpenAI
ทำไม Tier 1 ของฉันช้ากว่าของเพื่อนร่วมงาน?
rate limit เป็นระดับ organization ไม่ใช่ต่อ API key หาก key ของคุณอยู่ใน organization ที่มีคนอื่นใช้งานหนัก คุณกำลังแชร์ quota กับ traffic ของพวกเขา
วิธีตรวจสอบคือรัน request เดียวกันจากทั้งสอง key แล้วเทียบค่า:
x-ratelimit-remaining-requests
x-ratelimit-remaining-tokens
จะรู้ได้อย่างไรว่าแต่ละโมเดลมี limit เท่าไร?
ให้ส่ง request ราคาถูกหนึ่งครั้งไปยังแต่ละโมเดล แล้วอ่าน response headers อย่าอ้างอิงจากตารางทั่วไปอย่างเดียว เพราะโมเดลหรือ snapshot version ต่างกันอาจมี limit ต่างกัน เช่น:
gpt-5.5
gpt-5.5-0901
Streaming request นับต่างจาก request ปกติไหม?
สำหรับ TPM มีผล เพราะ streaming request อาจ reserve token ตาม max_tokens ดังนั้นถ้าตั้ง max_tokens สูงเกินจริง อาจกิน TPM budget แม้ response จริงจะสั้น
แนวทางคือกำหนด max_tokens ให้ใกล้เคียง maximum output ที่ต้องการจริง อ่านเพิ่มเติมได้ที่ วิธีทดสอบ ChatGPT API ด้วย Apidog
แชร์ rate limit test กับทีมได้ไหม?
ได้ บันทึก request และ test scenario ไว้ใน shared project ของ Apidog จากนั้นให้สมาชิกทีมเปลี่ยน environment เป็น API key ของตัวเองแล้วรัน scenario เดิมได้ทันที วิธีนี้ช่วยตอบคำถามอย่าง “เป็น key ของฉันที่โดน limit หรือเป็นทั้ง organization?” ได้เร็วขึ้น
Top comments (0)