

เวลาทำ API ให้เว็บกับแอปเรียกใช้ ช่วงแรกเราอาจมองเห็นคำขอเป็นรายการคล้ายๆ กัน มีคนเรียกเข้ามา ระบบตรวจข้อมูลแล้วตอบกลับ จึงดูเหมือนว่าถ้ากำหนดจำนวนครั้งต่อช่วงเวลาไว้ ก็น่าจะช่วยควบคุมภาระได้พอสมควร
แต่พอมีงานหลายลักษณะอยู่หลัง API เดียวกัน ความต่างจะเริ่มชัดขึ้น การขอดูชื่อสินค้าหนึ่งรายการกับการขอออกรายงานทั้งเดือนอาจนับเป็นหนึ่ง request เท่ากัน ทั้งที่งานหลังต้องอ่านข้อมูล ประมวลผล และเก็บไฟล์เพิ่มอีกหลายขั้น หากนับเฉพาะจำนวนครั้ง เราก็ยังไม่เห็นส่วนที่ใช้ทรัพยากรจริง
การตั้ง rate limit จึงควรเริ่มจากคำถามว่างานแบบไหนกำลังแย่งทรัพยากรกับใคร และต้องการรักษาบริการส่วนใดให้ใช้งานได้ก่อน เมื่อเห็นภาพนี้แล้วจึงค่อยเลือกว่าจะนับที่ระดับผู้ใช้ IP หรือทั้งระบบครับ
สมมติว่ามี endpoint สำหรับค้นข้อมูล ซึ่งผู้เรียกเลือกจำนวนรายการต่อหน้าได้ หากปล่อยให้เลือกได้เท่าไรก็ได้ การจำกัดจำนวน request อย่างเดียวก็ยังเปิดให้แต่ละคำขอขยายงานได้มาก ทั้งจำนวนแถวที่อ่าน ขนาดผลลัพธ์ และหน่วยความจำที่ต้องใช้ก่อนตอบกลับ
ตรงนี้จึงมีข้อจำกัดอีกกลุ่มที่ควรทำคู่กัน เช่น จำนวนรายการต่อหน้า ขนาดชุดข้อมูลที่ส่งเข้ามาครั้งเดียว ความยาวข้อความ และระยะเวลาที่อนุญาตให้งานทำต่อ ข้อจำกัดเหล่านี้ช่วยกำหนดขนาดของหนึ่งงาน ก่อนที่ตัวนับความถี่จะเข้ามาควบคุมว่ารับงานขนาดนั้นได้บ่อยเพียงใด
ถ้างานต้องเรียกบริการภายนอก ก็ต้องนับภาระปลายทางด้วย คำขอที่ใช้ CPU ฝั่งเราน้อยอาจสร้างงานจำนวนมากให้อีกระบบได้ การออกแบบจึงต้องไล่ตามเส้นทางทำงาน ไม่หยุดเพียงเพราะเครื่อง API ยังดูว่างอยู่
สำหรับค่าที่ผู้เรียกเลือกได้ ควรตรวจขอบเขตก่อนเริ่มอ่านข้อมูลก้อนใหญ่ด้วย การรับคำขอแล้วค่อยมาปฏิเสธหลังสร้างผลลัพธ์เสร็จ อาจยังเสียทรัพยากรส่วนที่ต้องการป้องกันไปแล้ว

Rate limit บอกขอบเขตการเริ่มคำขอในช่วงเวลา ส่วน concurrency limit บอกจำนวนงานที่กำลังค้างอยู่พร้อมกัน ลองนึกถึงงานสร้างรายงานที่ใช้เวลานาน แม้ผู้ใช้จะเริ่มงานไม่ถี่ แต่ถ้างานเก่ายังไม่จบ งานใหม่ก็สะสมจนแย่ง connection และหน่วยความจำกันได้
การย้ายงานเข้าคิวช่วยแยกจังหวะรับกับจังหวะประมวลผล แต่คิวเองก็ต้องมีขอบเขต ถ้ารับทุกอย่างแล้วปล่อยให้รอไปเรื่อยๆ ปัญหาอาจเปลี่ยนจากเครื่องทำงานพร้อมกันมากเกินไปเป็นคนใช้รอโดยไม่รู้ว่าจะได้ผลเมื่อไร จึงต้องคิดทั้งความยาวคิว เวลารอ และทางจัดการงานที่หมดประโยชน์แล้ว
สำหรับงานที่มีผลข้างเคียง การหมดเวลารอของผู้เรียกก็ไม่ใช่หลักฐานว่างานหยุดแล้ว ก่อนอนุญาตให้ลองใหม่ต้องดูสถานะงานเดิมและกติกา idempotency ควบคู่กัน ไม่เช่นนั้นระบบอาจลดจำนวนคำขอหน้าบ้านได้ แต่กลับสร้างงานซ้ำอยู่หลังคิว
IP เป็นข้อมูลที่หาได้ตั้งแต่ต้นทาง แต่ไม่ได้แทนคนหนึ่งคนเสมอไป ผู้ใช้หลายคนในสำนักงานหรือเครือข่ายมือถืออาจออกอินเทอร์เน็ตผ่าน IP เดียวกัน หากใช้โควตาต่อ IP อย่างเข้มงวดกับทุกงาน คนหนึ่งใช้งานหนักก็อาจทำให้คนอื่นถูกปฏิเสธไปด้วย
ในงานที่เข้าสู่ระบบแล้ว เราอาจต้องมีขอบเขตระดับบัญชีหรือองค์กรเพิ่มเข้ามา เพื่อให้โควตาสอดคล้องกับเจ้าของงาน ส่วน endpoint สาธารณะที่ยังไม่รู้ตัวตนก็ต้องเลือกสัญญาณอื่นตามบริบท โดยยอมรับว่าตัวตนที่มองเห็นมีความแน่นอนต่างกัน การจำกัดหลายชั้นจึงควรมีเหตุผลของแต่ละชั้น ไม่ใช่เพิ่มตัวนับเหมือนกันทุกจุด
ถ้า API อยู่หลัง proxy ต้องรู้ด้วยว่า IP ที่นำมาใช้มาจากจุดใด และเชื่อถือ header จาก proxy ใดบ้าง การอ่านค่าที่ผู้เรียกใส่มาเองโดยไม่มีขอบเขตความเชื่อถือ อาจทำให้กติกาที่ตั้งใจจำกัดต่อ IP ไม่ได้จำกัดตามต้นทางที่คิดไว้
อีกด้านหนึ่งคือจำนวน instance ของ API หากแต่ละเครื่องมีตัวนับในหน่วยความจำของตัวเอง โควตาที่เห็นจากทั้งระบบอาจต่างจากที่ตั้งต่อเครื่อง การเพิ่ม replica จึงต้องตรวจขอบเขตของตัวนับและการประสานข้อมูลด้วย ไม่ถือว่าค่าตัวเลขเดิมยังมีความหมายเท่าเดิมโดยอัตโนมัติ

HTTP 429 ใช้สื่อว่าผู้เรียกส่งคำขอมากเกินขอบเขตในช่วงเวลาหนึ่ง โดยมาตรฐานไม่ได้กำหนดให้ทุกบริการต้องนับผู้ใช้หรือหน้าต่างเวลาแบบเดียวกัน รายละเอียดของนโยบายจึงต้องมีในสัญญา API และข้อความตอบกลับควรอธิบายปัญหาได้โดยไม่เปิดเผยข้อมูลของบัญชีอื่น
บริการอาจส่ง Retry-After เพื่อบอกจังหวะที่ควรลองอีกครั้ง แต่ไม่ได้หมายความว่าทุก 429 จำเป็นต้องมี header นี้ หรือการรอครบแล้วจะรับรองว่างานต้องสำเร็จ ฝั่งเรียกยังต้องจำกัดจำนวน retry และระยะเวลารวม ไม่สร้างการลองใหม่พร้อมกันจนภาระกลับมาเป็นคลื่นอีกครั้ง
ส่วนกรณีเครื่องหรือบริการปลายทางกำลังขัดข้องทั้งระบบ ต้องแยกจากการใช้โควตาของผู้เรียกคนใดคนหนึ่ง การบอกสาเหตุให้ตรงช่วยทั้งคนใช้และคนดูแล เพราะการเพิ่มโควตาให้บัญชีไม่ได้แก้ connection ที่หมดจากปัญหาอีกชนิดหนึ่ง
ก่อนเลือกตัวเลขควรแยกกลุ่มงานที่สำคัญ เช่น การอ่านสถานะงานเดิมกับการเริ่มออกรายงานใหม่ หากทุกอย่างใช้ช่องทางเดียวกันจนงานหนักกินสิทธิ์ทั้งหมด คนใช้ก็อาจไม่มีทางตามผลของงานที่ระบบรับไปแล้ว การรักษาทางอ่านสถานะหรือยกเลิกจึงเป็นส่วนหนึ่งของการออกแบบบริการด้วย
การตรวจควรใช้ข้อมูลทดลองที่ควบคุมได้ ดูทั้งคำขอเล็ก คำขอใหญ่ งานที่ค้างนาน และผู้ใช้หลายรายที่ใช้ IP ร่วมกัน พร้อมตรวจว่าการปฏิเสธเกิดก่อนจุดใช้ทรัพยากรหนักตามที่ตั้งใจจริง บทนี้ยังไม่มีผลทดสอบความจุ จึงไม่มีจำนวน request หรือจำนวนงานพร้อมกันที่รับรองว่าเหมาะกับระบบของผู้อ่านทุกแบบ
การจำกัด API ให้ได้ผลต้องมองทั้งขนาดของหนึ่งงาน ความถี่ จำนวนงานพร้อมกัน และขอบเขตเจ้าของงาน เมื่อแยกสิ่งเหล่านี้ออกจากกันได้ เราจะตั้งกติกาที่สัมพันธ์กับภาระจริง และตอบผู้เรียกได้ชัดขึ้นว่าควรรอ ลดขนาดงาน หรือตรวจสถานะเดิม ส่วนตัวเลขสุดท้ายยังต้องตรวจจากสภาพบริการที่จะใช้งานจริง