Rate Limiting vs Throttling: Dua Senjata Utama Mengendalikan Traffic di Sistem Skala Besar
Traffic di dunia nyata tidak pernah datang dengan teratur. Dalam satu momen, sistem bisa menerima puluhan ribu request sekaligus akibat flash sale, viral event, atau serangan bot. Tanpa mekanisme pengendalian, sistem yang secara teori mampu menangani beban tinggi bisa runtuh hanya karena satu jenis traffic yang salah. Di sinilah rate limiting dan throttling berperan — keduanya adalah mekanisme kontrol traffic yang sering dipakai bersamaan, tapi memiliki tujuan, cara kerja, dan tempat yang berbeda dalam arsitektur. Memahami perbedaan keduanya adalah modal dasar untuk membangun sistem yang benar-benar tahan banting.
Dua Pertanyaan Berbeda
Sebelum masuk ke detail implementasi, penting untuk memahami bahwa rate limiting dan throttling menjawab dua pertanyaan yang secara fundamental berbeda.
Rate Limiting → "Apakah request ini boleh masuk?"
Throttling → "Seberapa cepat request ini boleh diproses?"
Perbedaan ini bukan sekadar semantik. Implikasinya langsung mempengaruhi di mana kamu menempatkan kontrol, bagaimana sistem berperilaku saat overload, dan apa yang dirasakan oleh client.
flowchart TD
A[Client Request] --> B{Rate Limit Check}
B -- Limit terlampaui --> C[429 Too Many Requests]
B -- Masih dalam batas --> D{Throttle Check}
D -- Sistem overload --> E[Masuk Queue / Ditunda]
D -- Kapasitas tersedia --> F[Diproses Backend]
E --> FRate limiting berada di pintu masuk — ia memutuskan boleh atau tidak. Throttling berada di dalam sistem — ia memutuskan seberapa cepat. Mengandalkan hanya salah satu adalah desain yang tidak lengkap.
Rate Limiting
Rate limiting adalah mekanisme yang membatasi jumlah maksimum request dari suatu entitas — bisa berupa user, IP address, API key, device, atau tenant — dalam interval waktu tertentu. Jika limit terlampaui, request langsung ditolak dengan HTTP 429 (Too Many Requests). Tidak ada penundaan, tidak ada antrian — hanya accept atau reject.
Mental Model
Bayangkan sebuah tiket masuk konser dengan kapasitas 100 orang per jam. Begitu kuota terpenuhi, orang ke-101 langsung diminta pergi — tidak peduli seberapa penting urusannya. Rate limiting bekerja persis seperti itu.
Jatah user A: 100 request/menit
Request ke-101 dalam satu menit → 429, tolak
Request ke-1 di menit berikutnya → boleh masuk
Algoritma Rate Limiting
Ada beberapa algoritma yang umum digunakan, masing-masing dengan trade-off berbeda.
Fixed Window Counter adalah yang paling sederhana — counter di-reset setiap interval waktu tetap (misalnya tiap menit). Masalah utamanya adalah boundary burst: user bisa mengirim 100 request di detik ke-59, lalu 100 request lagi di detik ke-61, sehingga dalam rentang 2 detik sebenarnya ada 200 request yang lolos.
sequenceDiagram
participant Client
participant Counter
Client->>Counter: 100 request (detik ke-59)
Note over Counter: Window reset
Client->>Counter: 100 request (detik ke-61)
Note over Counter: 200 request dalam 2 detik — window tidak mendeteksi iniSliding Window memecahkan masalah ini dengan menghitung request dalam window yang bergerak mengikuti waktu saat ini. Lebih akurat tapi lebih mahal secara komputasi.
Token Bucket mengisi “bucket” dengan token secara periodik. Setiap request membutuhkan satu token. Keunggulannya adalah mendukung burst terkontrol — selama ada token tersisa, request bisa dilayani bahkan di atas rata-rata normal. Algoritma ini sangat populer untuk API publik.
Leaky Bucket (versi hard limit) bekerja seperti ember bocor — request masuk ke antrian berkapasitas tetap dan diproses dengan laju konstan. Request yang melebihi kapasitas antrian langsung ditolak.
flowchart LR
A[Request Masuk] --> B{Ada Token?}
B -- Ya --> C[Konsumsi 1 Token]
B -- Tidak --> D[429 Reject]
C --> E[Proses Request]
F[Refill Periodik] --> BUse Case Rate Limiting di Produksi
Public API dan SaaS Platform — Rate limiting adalah fondasi monetisasi berbasis tier. Free tier mendapat 60 req/menit, Pro tier 600 req/menit, Enterprise mendapat kuota custom. Tanpa ini, user free tier bisa menghabiskan seluruh kapasitas infrastruktur.
Endpoint Autentikasi — Login, OTP, dan password reset adalah target paling kritis untuk brute force dan credential stuffing. Rate limiting yang ketat di endpoint ini bisa memblokir serangan sebelum mencapai database.
// ANTI-PATTERN: endpoint login tanpa rate limit
POST /auth/login
→ attacker bisa mencoba jutaan kombinasi password
// BENAR: terapkan rate limit berlapis
POST /auth/login
→ max 5 percobaan per IP per menit
→ max 10 percobaan per username per jam
→ lockout sementara setelah threshold tercapai
Multi-Tenant Fairness — Dalam sistem multi-tenant, satu tenant yang agresif bisa menghabiskan resource bersama dan membuat tenant lain menderita (noisy neighbor problem). Rate limiting per-tenant menjaga isolasi logical di antara mereka.
Throttling
Throttling adalah mekanisme untuk mengatur laju pemrosesan request ketika sistem mendekati atau melewati kapasitasnya. Berbeda dengan rate limiting yang menolak request, throttling tetap menerima request — hanya saja memprosesnya lebih lambat, menundanya, atau memasukkannya ke antrian.
Mental Model
Bayangkan sebuah restoran yang penuh. Daripada mengusir tamu baru, mereka meminta tamu menunggu di area tunggu. Makanan tetap akan datang, hanya butuh waktu lebih lama. Throttling bekerja seperti itu.
Sistem menerima 10.000 request/detik
Kapasitas backend: 1.000 request/detik
Throttling: 9.000 request masuk antrian, diproses secara bertahap
Hasilnya: latency naik, tapi tidak ada request yang hilang
Mekanisme Throttling
Queue-based Throttling memasukkan request ke dalam antrian dan memprosesnya sesuai kapasitas yang tersedia. Simpel, tapi berisiko memory pressure jika antrian tidak dibatasi.
Concurrency Limiting membatasi jumlah proses yang boleh berjalan secara bersamaan, bukan jumlah request per waktu. Cocok untuk task yang CPU-bound atau yang membutuhkan resource eksklusif.
Adaptive Throttling menyesuaikan laju pemrosesan secara dinamis berdasarkan kondisi runtime — CPU usage, memory, latency, atau error rate. Ini yang digunakan di service mesh modern seperti Istio dan Envoy.
Backpressure adalah pola di mana downstream service memberi sinyal ke upstream untuk melambat. Daripada antrian menumpuk diam-diam, sistem secara eksplisit mengomunikasikan kapasitasnya.
sequenceDiagram
participant ServiceA
participant ServiceB
participant Queue
ServiceA->>ServiceB: 10.000 req/s
ServiceB->>Queue: Terima semua, antri yang tidak bisa diproses
Queue-->>ServiceA: Backpressure signal: "Saya hanya bisa 1.000/s"
ServiceA->>ServiceB: Turunkan ke 1.000 req/s
Note over ServiceB: Sistem stabil, tidak ada yang crashUse Case Throttling di Produksi
Microservices dan Service-to-Service Communication — Ketika Service A memanggil Service B yang mulai overload, tanpa throttling Service A akan terus melakukan retry yang memperparah situasi (retry storm). Dengan throttling, Service A melambat secara proporsional dan cascade failure bisa dicegah.
// ANTI-PATTERN: retry tanpa batas saat service downstream lambat
while (!success) {
response = callServiceB(); // retry terus
// akibat: Service B semakin tenggelam
}
// BENAR: throttle request dengan exponential backoff
response = callServiceB();
if (response.isOverloaded) {
throttle.wait(); // tunggu sesuai sinyal kapasitas
// Service B punya ruang untuk pulih
}
Background Job dan Event Consumer — Worker yang memproses Kafka atau SQS tidak perlu memproses semua pesan secepat mungkin. Lebih baik backlog naik sementara daripada worker crash dan pesan benar-benar hilang.
Financial dan Mission-Critical System — Transaksi pembayaran tidak boleh di-drop. Dalam sistem ini, throttling adalah pilihan natural: latency bisa ditoleransi, tapi kehilangan transaksi tidak bisa.
Perbedaan Fundamental
Setelah memahami keduanya, perbedaannya menjadi sangat jelas.
| Dimensi | Rate Limiting | Throttling |
|---|---|---|
| Pertanyaan utama | Boleh masuk? | Seberapa cepat? |
| Nasib request berlebih | Ditolak (429) | Ditunda / diantri |
| Lokasi dalam arsitektur | Edge, API Gateway, CDN | Internal service, service mesh |
| Dampak ke client | Error eksplisit | Latency naik |
| Fokus utama | Security & fairness | Stability & resilience |
| Sifat kontrol | Hard limit | Soft control |
| Visibilitas ke client | Langsung terasa (error) | Sering tidak terlihat |
flowchart LR
subgraph Eksternal
A[Client]
B[API Gateway\nRate Limiting]
end
subgraph Internal
C[Service Mesh\nThrottling]
D[Service A]
E[Service B]
F[Database]
end
A --> B
B -- Request lolos --> C
C --> D
D --> E
E --> FRate limiting menjaga pintu masuk — memastikan tidak ada entitas yang bisa membanjiri sistem. Throttling menjaga organ dalam — memastikan komponen internal tidak saling menghancurkan saat load tinggi.
Mengapa Keduanya Selalu Dibutuhkan
Mengandalkan hanya satu mekanisme adalah design smell. Berikut kenapa.
Hanya Rate Limiting Tanpa Throttling
Anggap kamu membatasi setiap user hanya 100 req/menit. Jika ada 10.000 user aktif, backend tetap menerima 1 juta request per menit — angka yang mungkin jauh di atas kapasitas service internalmu. Rate limit melindungi kamu dari satu user yang agresif, tapi tidak dari kombinasi banyak user normal.
// Skenario: rate limit aman, tapi backend tetap bisa overload
10.000 user × 100 req/menit = 1.000.000 req/menit ke backend
Kapasitas backend: 500.000 req/menit
Hasil: backend overload meski tidak ada user yang melanggar rate limit
Hanya Throttling Tanpa Rate Limiting
Tanpa rate limit di edge, satu user atau satu bot bisa memenuhi seluruh antrian throttling. User lain yang sah akan terkena dampaknya karena antrian mereka ikut penuh.
// Skenario: throttling ada, tapi tidak ada rate limit
Bot mengirim 100.000 request → memenuhi antrian
User sah kirim 1 request → masuk ke ujung antrian yang panjang
Hasil: bot dapat prioritas, user sah tidak terlayani
Kombinasi yang Tepat
flowchart TD
A[Client] --> B[API Gateway]
subgraph B[API Gateway]
B1[Rate Limit per User/IP/Key]
end
B --> C[Load Balancer]
subgraph C[Service Layer]
C1[Throttling per Service]
C2[Backpressure Signal]
end
C --> D[Backend Services]
D --> E[Database / Cache]
C2 -.-> B1Dengan kombinasi ini:
- Tidak ada user yang bisa abuse sistem dari luar
- Tidak ada komponen internal yang bisa membanjiri komponen lain
- Sistem bisa melakukan graceful degradation saat load naik
Anti-Pattern yang Harus Dihindari
// ✗ Anti-pattern 1: Rate limit terlalu ketat
Limit: 10 req/menit untuk semua endpoint
Akibat: user sah terkena limit saat operasi normal seperti load page
✓ Solusi: sesuaikan limit dengan pola penggunaan normal; gunakan tier berbeda
untuk endpoint berbeda (autentikasi vs read vs write)
// ✗ Anti-pattern 2: Throttling tanpa batas antrian
Queue.add(request) // tidak ada max size
Akibat: antrian tumbuh tak terkendali → memory habis → crash lebih parah
✓ Solusi: selalu set max queue size; request yang melebihi kapasitas antrian
lebih baik di-reject daripada memori server habis
// ✗ Anti-pattern 3: Rate limit global tanpa diferensiasi entitas
if (totalRequestCount > 10000) reject() // semua user kena efeknya
Akibat: satu bot yang agresif bisa membuat semua user sah ikut kena limit
✓ Solusi: rate limit selalu per entitas (per user, per IP, per API key),
bukan per total request ke sistem
// ✗ Anti-pattern 4: Throttling tanpa monitoring
Throttle aktif tapi tidak ada alert atau metrik
Akibat: tim tidak tahu kapan sistem mulai kewalahan sampai sudah terlambat
✓ Solusi: monitor queue length, throttle activation rate, dan p99 latency
sebagai signal kesehatan sistem
Checklist Implementasi
RATE LIMITING:
□ Diterapkan di layer edge (API Gateway / reverse proxy)
□ Granularitas per entitas: user ID, IP, API key, atau tenant
□ Algoritma dipilih sesuai kebutuhan: token bucket untuk burst,
sliding window untuk akurasi tinggi
□ Response 429 menyertakan header Retry-After
□ Limit berbeda untuk endpoint berbeda (autentikasi lebih ketat)
□ Limit berbeda untuk tier user berbeda (free vs pro vs enterprise)
THROTTLING:
□ Diterapkan di service-to-service call dan background worker
□ Antrian punya batas maksimum (tidak infinite queue)
□ Ada mekanisme backpressure ke upstream
□ Adaptive throttling mempertimbangkan CPU, latency, dan error rate
□ Timeout dikonfigurasi agar request tidak menunggu terlalu lama
MONITORING:
□ Metrik rate limit hits per endpoint per waktu
□ Metrik queue length dan queue wait time
□ Alert saat throttle activation rate melebihi threshold normal
□ Dashboard p50, p95, p99 latency per service
□ Limit dan kapasitas terdokumentasi di API documentation
Ringkasan
- Rate limiting menjawab “boleh atau tidak” — ia berada di edge, menolak request yang melebihi kuota dengan HTTP 429, dan fokus pada proteksi dan fairness.
- Throttling menjawab “seberapa cepat” — ia berada di dalam sistem, memperlambat atau mengantri request saat kapasitas penuh, dan fokus pada stabilitas.
- Token bucket adalah algoritma rate limiting paling fleksibel karena mendukung burst terkontrol; cocok untuk API publik.
- Backpressure adalah pola throttling yang paling sehat di arsitektur microservices — downstream memberi sinyal ke upstream, bukan diam-diam menumpuk beban.
- Keduanya selalu dibutuhkan — rate limit melindungi dari abuse eksternal, throttling melindungi dari overload internal. Mengandalkan hanya salah satu adalah desain yang tidak lengkap.
- Anti-pattern paling umum: rate limit terlalu ketat merusak user experience; throttling tanpa batas antrian bisa menyebabkan crash lebih parah dari masalah aslinya.
- Selalu monitor queue length, throttle activation rate, dan latency percentile — ketiganya adalah indikator paling awal bahwa sistem mulai kewalahan.