API Rate Limiting & Concurrency Control

ข้อกำหนดการจำกัดการเรียกใช้งาน API เพื่อป้องกันการใช้งานเกินขีดจำกัดของระบบ

เพื่อให้ระบบมีเสถียรภาพและสามารถให้บริการผู้ใช้งานทุกคนได้อย่างมีประสิทธิภาพ
API นี้มีการกำหนด Rate Limiting และ Concurrency Control

หาก Client ส่ง request เกินกว่าข้อจำกัดที่กำหนด ระบบจะตอบกลับด้วย

HTTP 429 Too Many Requests


Limit Summary

PolicyScopeLimit
ClientTokenLimitPOST /api/v1/clienttoken (จำกัดตาม IP Address ของผู้เรียก ไม่ใช่ Client Token — เนื่องจาก request นี้ยังไม่มี token)10 requests per minute
InsertFile/FileVaultPOST /api/v1/{transaction}/insertFile,
POST /api/v1/fileVault
10 concurrent requests
GetConcurrencyLimitByUserTokenGET ต่อ User Token20 concurrent requests
PostConcurrencyLimitByUserTokenPOST ต่อ User Token10 concurrent requests
FinancialReportLimit + FinancialReportConcurrencyLimit (combined)GET /api/v1/FinancialReports/trialbalance ต่อ User Token10 requests per minute และ 1 concurrent request

Note: Concurrency limit จะนับเฉพาะ request ที่ยังประมวลผลไม่เสร็จ หรือยังไม่ได้รับ response เท่านั้น

Note: GetConcurrencyLimitByUserToken และ PostConcurrencyLimitByUserToken มีผลเฉพาะ endpoint ที่ระบบกำหนดให้ใช้ policy นี้เท่านั้น ไม่ใช่ทุก endpoint ของระบบ


Rate Limit Policy

Rate limit ใช้เพื่อจำกัดจำนวน request ภายในช่วงเวลาที่กำหนด

Client Token Scope

EndpointScopeRate Limit
POST /api/v1/clienttokenต่อ IP Address ของผู้เรียก10 requests per minute

หมายเหตุเรื่อง Scope: เนื่องจาก endpoint นี้ใช้สำหรับขอ Client Token ก่อนที่ client จะมี token ใดๆ ระบบจึงไม่สามารถจำกัดตาม token ได้ และใช้ IP Address ของผู้เรียก เป็น scope ในการนับจำนวน request แทน ผลคือ IP เดียวกันที่ยิงหลาย request (เช่นอยู่หลัง NAT/proxy เดียวกัน) จะถูกนับรวมกันในโควต้าเดียว

Example

หาก client ส่ง request มากกว่า 10 ครั้งภายใน 1 นาที (จาก IP เดียวกัน)
ระบบจะตอบกลับ

HTTP 429 Too Many Requests

ตัวอย่าง response

{
  "error": "RATE_LIMITED",
  "type": "rate",
  "policy": "ClientTokenLimit",
  "retryAfterSeconds": 60,
  "message": "Too many requests. Please retry later.",
  "path": "/api/v1/clienttoken",
  "timestamp": "2026-03-12T14:20:00+07:00"
}

Concurrency Limit Policy

Concurrency limit คือการจำกัดจำนวน request ที่กำลังประมวลผลพร้อมกัน (in-flight requests)

Concurrency limit ถูกกำหนด ต่อ User Token และมีผลเฉพาะ endpoint ที่ระบบกำหนดให้ใช้ policy นี้เท่านั้น (ดูตาราง Limit Summary)

HTTP MethodConcurrent Limit
GET20 concurrent requests
POST10 concurrent requests

ความหมาย

  • สำหรับ endpoint ที่ใช้ policy นี้ สามารถมี GET requests ที่กำลังประมวลผลพร้อมกันได้สูงสุด 20 requests ต่อ User Token
  • สำหรับ endpoint ที่ใช้ policy นี้ สามารถมี POST requests ที่กำลังประมวลผลพร้อมกันได้สูงสุด 10 requests ต่อ User Token

หากมี request ใหม่เข้ามาในขณะที่จำนวน concurrent request เกินกว่าที่กำหนด
ระบบจะปฏิเสธ request นั้นทันที


Concurrency Scope

Concurrency limit ถูกกำหนด ต่อ User Token

หมายความว่า

  • User Token แต่ละตัวมี limit ของตัวเอง
  • การใช้งานของ token หนึ่งจะไม่กระทบ token อื่น

Example

User TokenConcurrent GET Requests
token-A20
token-B20

หาก

  • token-A ยิง GET 20 requests พร้อมกัน
  • token-B ยังสามารถยิง GET ได้อีก 20 requests

เมื่อ request ถูกปฏิเสธเนื่องจากเกิน limit ระบบจะตอบกลับเป็น JSON ดังนี้

HTTP 429 Too Many Requests

ตัวอย่าง response

{
  "error": "RATE_LIMITED",
  "type": "concurrency",
  "policy": "GetConcurrencyLimitByUserToken",
  "retryAfterSeconds": null,
  "message": "Too many concurrent requests. Please wait until the previous request completes before retrying.",
  "path": "/api/v1/resource",
  "timestamp": "2026-03-12T14:20:00+07:00"
}

Financial Reports: Trial Balance (Combined Limit)

GET /api/v1/FinancialReports/trialbalance มีข้อจำกัดเข้มงวดกว่า endpoint GET ทั่วไป เนื่องจากเป็น report ที่ใช้ทรัพยากรประมวลผลสูง โดยถูกจำกัดด้วย สองนโยบายพร้อมกัน ต่อ User Token เดียวกัน:

PolicyLimit
FinancialReportLimit (rate)10 requests per minute
FinancialReportConcurrencyLimit (concurrency)1 concurrent request

ความหมาย

  • User Token เดียวกันเรียก endpoint นี้ได้ไม่เกิน 10 ครั้งต่อนาที
  • และในเวลาเดียวกัน เรียกพร้อมกันได้สูงสุดเพียง 1 request เท่านั้น (request ที่ 2 ที่ยิงเข้ามาก่อน request แรกจะประมวลผลเสร็จ จะถูกปฏิเสธทันที)

Limit นี้แยกต่างหากจาก GetConcurrencyLimitByUserToken (20 concurrent) ที่ใช้กับ GET endpoint ทั่วไป — endpoint นี้ไม่ได้ใช้ policy 20 concurrent แต่ใช้ policy เฉพาะของตัวเองแทน


Response Fields
FieldTypeDescription
errorstringError code
typestringLimit type (rate หรือ concurrency)
policystringRate limit policy ที่ถูก trigger
retryAfterSecondsnumber/nullระยะเวลาที่ควรรอก่อน retry
messagestringรายละเอียดของ error
pathstringAPI endpoint
timestampstringเวลาที่เกิดเหตุการณ์

Example Scenario

GET Request Example

Limit

20 concurrent GET requests per User Token

สถานการณ์

UserToken-A ส่ง GET request พร้อมกัน 25 requests

ผลลัพธ์

  • 20 requests แรก → ระบบประมวลผล
  • 5 requests ที่เหลือ → ได้รับ 429 Too Many Requests

POST Request Example

Limit

10 concurrent POST requests per User Token

สถานการณ์

UserToken-A ส่ง POST request พร้อมกัน 15 requests

ผลลัพธ์

  • 10 requests แรก → ระบบประมวลผล
  • 5 requests ที่เหลือ → ได้รับ 429 Too Many Requests

Trial Balance Example

Limit

1 concurrent request + 10 requests/minute per User Token

สถานการณ์

UserToken-A ส่ง GET /api/v1/FinancialReports/trialbalance พร้อมกัน 3 requests

ผลลัพธ์

  • 1 request แรก → ระบบประมวลผล
  • 2 requests ที่เหลือ → ได้รับ 429 Too Many Requests (concurrency)

Recommended Client Behavior

เมื่อ client ได้รับ HTTP 429

ScenarioRecommended Action
Rate limit exceededรอเวลาที่กำหนดใน retryAfterSeconds ก่อน retry
Concurrency limit exceededรอให้ request ก่อนหน้าประมวลผลเสร็จก่อนส่ง request ใหม่

Warning: ไม่ควร retry ทันทีหลังได้รับ 429 เพราะอาจทำให้ชน limit ซ้ำและเพิ่มภาระให้ระบบ


Best Practices

Limit Parallel Requests

หลีกเลี่ยงการยิง request พร้อมกันจำนวนมาก โดยเฉพาะ endpoint ที่มี concurrency limit ต่ำ เช่น FinancialReports/trialbalance (1 concurrent request)

Implement Request Queue

ให้ client จัดการ queue ของ request

Use Retry with Backoff

เมื่อ request ล้มเหลวจากข้อจำกัดชั่วคราว เช่น HTTP 429 Too Many Requests
client ไม่ควร retry ทันที เพราะอาจทำให้ชน limit ซ้ำและเพิ่มภาระให้ระบบ

ควรรอระยะเวลาหนึ่งก่อน retry และเพิ่มระยะเวลาการรอในแต่ละรอบที่ retry ไม่สำเร็จ

ตัวอย่าง:

  • ครั้งที่ 1 รอ 1 วินาที
  • ครั้งที่ 2 รอ 2 วินาที
  • ครั้งที่ 3 รอ 4 วินาที
  • ครั้งที่ 4 รอ 8 วินาที

หาก response มี header Retry-After
client ควรรอตามเวลาที่ server ระบุก่อน retry

Tip: ถ้ามี Retry-After ให้ยึดค่าจาก server ก่อนใช้ backoff ที่ client กำหนดเอง

Monitor API Usage

ติดตามการใช้งาน API ของ client อย่างสม่ำเสมอ


Troubleshooting & Support

ทำไมถึงได้ HTTP 429

สาเหตุที่เป็นไปได้

  • ส่ง request ถี่เกิน limit ที่กำหนด
  • ส่ง request พร้อมกันเกิน concurrency limit
  • request ก่อนหน้ายังประมวลผลไม่เสร็จ
  • เรียก GET /api/v1/FinancialReports/trialbalance ซ้อนกันมากกว่า 1 request ในเวลาเดียวกัน (endpoint นี้จำกัดเข้มกว่า GET ทั่วไป)

ควรส่งอะไรให้ทีม Support

  • Request timestamp
  • API endpoint
  • Response body
  • Correlation ID (ถ้ามี)

ข้อมูลเหล่านี้จะช่วยให้ทีมสามารถตรวจสอบปัญหาได้รวดเร็วขึ้น