Panduan Komprehensif: Mengamankan API RESTful dengan Pembatasan Token Bucket dan APCu
Langkah demi langkah membangun sistem rate limiter performa tinggi pada aplikasi web berbasis PHP tanpa memerlukan server Redis eksternal.
Menjaga endpoint API dari permintaan berlebihan adalah keharusan bagi pengembang sistem. Pendekatan umum membebani basis data relasional atau mewajibkan kluster Redis yang menambah biaya operasional — padahal untuk banyak kasus, memori lokal sudah lebih dari cukup.
Mengapa Token Bucket, bukan penghitung sederhana
Penghitung per jendela waktu tetap mudah dibuat tetapi memiliki cacat yang terkenal. Batas seratus permintaan per menit dapat dilewati dengan dua ratus permintaan dalam dua detik, asalkan seratus pertama jatuh di akhir satu menit dan seratus berikutnya di awal menit berikutnya.
Token Bucket menghindari masalah ini. Setiap klien memiliki ember dengan kapasitas tertentu yang terisi ulang dengan laju tetap. Setiap permintaan mengambil satu token; jika ember kosong, permintaan ditolak. Modelnya mengizinkan lonjakan singkat sampai sebesar kapasitas ember, sambil membatasi laju rata-rata dalam jangka panjang.
Menempatkannya di APCu
APCu adalah cache memori bersama yang hidup di dalam proses PHP-FPM itu sendiri. Karena tidak ada lompatan jaringan, pengecekan kuota selesai dalam hitungan mikrodetik — dibandingkan sekitar satu milidetik untuk Redis pada jaringan lokal.
Operasi pembaruan harus atomik. Membaca nilai, menghitung, lalu menulis kembali menciptakan celah balapan antar worker yang berjalan bersamaan. Gunakan operasi penambahan atomik yang disediakan APCu, atau kunci ringan, agar dua permintaan simultan tidak sama-sama lolos dari ember yang sebenarnya tinggal berisi satu token.
Batas yang harus diketahui sejak awal
APCu bersifat lokal terhadap satu server. Pada satu mesin dengan banyak worker PHP-FPM, seluruh worker berbagi memori yang sama dan pendekatan ini bekerja sempurna. Begitu aplikasi berjalan di belakang penyeimbang beban dengan beberapa mesin, setiap mesin memiliki embernya sendiri — dan batas efektifnya menjadi berlipat sejumlah mesin.
Untuk kasus itu tersedia dua jalan: menerima pelonggaran tersebut dan menurunkan ambang per mesin, atau melakukan sinkronisasi berkala ke tabel persisten sehingga pelanggaran berat tetap tertangkap meski tidak seketika.
Menolak dengan benar
Penolakan harus menjawab dengan status 429 dan menyertakan header Retry-After, agar klien yang beritikad baik tahu kapan boleh mencoba lagi alih-alih mengulang segera dan memperburuk keadaan.
Dengan konfigurasi yang terukur, arsitektur ini menolak lonjakan puluhan ribu permintaan per detik dengan penggunaan memori yang tetap kecil dan dapat diperkirakan — tanpa satu pun proses tambahan yang perlu dijalankan dan dipantau.
Budi Santoso
Kontributor RedaksiSenior Software Architect dan pemerhati ekosistem PHP, cloud computing, dan performa web skala besar.
Artikel Terkait
Lihat Semua →Observability dengan Anggaran Terbatas: Log Terstruktur, Metrik, dan Jejak Seperlunya
20 Sep 2026
Implementasi Autentikasi Dua Faktor (2FA) Berbasis TOTP RFC 6238 Murni Tanpa Library Eksternal
11 Sep 2026
Optimalisasi MySQL 8 di Lingkungan Shared Hosting: Indexing, Buffer Pool, dan Slow Query
07 Sep 2026
Anatomi AI Image Generation: Dari Difusi Piksel Menuju Flow Matching
17 Okt 2026