Lewati ke konten

Algoritma Rate Limiting

distlimit mendukung 5 strategi algoritma rate-limiting. Setiap algoritma dikemas secara terpisah di bawah algorithm/<nama> dan dapat dipasangkan ke storage driver mana pun.


Algoritma Path Package Pola Trafik Kompleksitas Memori Struktur Data Redis Kasus Penggunaan Terbaik
Token Bucket algorithm/tokenbucket Ramah Burst $O(1)$ Hash Rate limiting API umum dengan toleransi lonjakan trafik.
Leaky Bucket algorithm/leakybucket Penataan Trafik $O(1)$ Hash Meratakan lonjakan trafik untuk layanan pihak ketiga.
Fixed Window algorithm/fixedwindow Reset Interval $O(1)$ String Counter Perlindungan endpoint sederhana & perisai brute-force login.
Sliding Window Log algorithm/slidinglog Presisi 100% Eksak $O(N)$ Sorted Set (ZSET) Transaksi keuangan & kuota kepatuhan ketat.
Sliding Window Counter algorithm/slidingcounter Moving Average Terbobot $O(1)$ Hash API terdistribusi trafik tinggi yang butuh akurasi memori $O(1)$.

Algoritma Token Bucket menjaga bucket berisi token yang diisi ulang dengan kecepatan konstan. Setiap request mengonsumsi 1 token. Jika token tersedia, request diizinkan.

flowchart LR
    Req[Incoming Request] --> Bucket[Bucket - Max Capacity]
    Refill[Refill Rate - Tokens / Sec] -->|Refills| Bucket
    Bucket -->|Token Available| Allowed[Allowed]
  • Kelebihan: Mengizinkan lonjakan (burst) hingga kapasitas maksimum bucket sambil menjaga rata-rata kecepatan request tetap stabil.
  • Contoh Penggunaan:
    import "github.com/balramadan/distlimit/algorithm/tokenbucket"
    limiter, _ := distlimit.New(
    driver,
    distlimit.WithLimit(100),
    distlimit.WithWindow(1*time.Minute),
    distlimit.WithAlgorithm(tokenbucket.New()),
    )

Algoritma Leaky Bucket memproses request pada kecepatan output yang tetap, tanpa memedulikan seberapa melonjaknya trafik masuk.

  • Kelebihan: Meratakan lonjakan trafik (traffic shaping) untuk melindungi microservices backend.
  • Contoh Penggunaan:
    import "github.com/balramadan/distlimit/algorithm/leakybucket"
    limiter, _ := distlimit.New(
    driver,
    distlimit.WithLimit(50),
    distlimit.WithWindow(1*time.Minute),
    distlimit.WithAlgorithm(leakybucket.New()),
    )

Membagi waktu ke dalam interval tetap (misal 12:00:00 - 12:01:00). Counter bertambah per window dan di-reset pada batas window.

  • Kelebihan: Sangat cepat dan ringan (memori $O(1)$, counter sederhana).
  • Kekurangan: Potensi lonjakan 2x limit pada batas jendela (boundary burst).
  • Contoh Penggunaan:
    import "github.com/balramadan/distlimit/algorithm/fixedwindow"
    limiter, _ := distlimit.New(
    driver,
    distlimit.WithLimit(1000),
    distlimit.WithWindow(1*time.Minute),
    distlimit.WithAlgorithm(fixedwindow.New()),
    )

4. Sliding Window Log (algorithm/slidinglog)

Section titled “4. Sliding Window Log (algorithm/slidinglog)”

Mencatat timestamp setiap request masuk dalam log terurut (ZSET di Redis). Membuang timestamp yang lebih tua dari durasi window.

  • Kelebihan: Presisi 100% eksak secara matematis di seluruh window waktu bergeser.
  • Kekurangan: Penggunaan memori lebih tinggi ($O(N)$ di mana $N$ adalah jumlah request dalam window).
  • Contoh Penggunaan:
    import "github.com/balramadan/distlimit/algorithm/slidinglog"
    limiter, _ := distlimit.New(
    driver,
    distlimit.WithLimit(10),
    distlimit.WithWindow(1*time.Minute),
    distlimit.WithAlgorithm(slidinglog.New()),
    )

5. Sliding Window Counter (algorithm/slidingcounter)

Section titled “5. Sliding Window Counter (algorithm/slidingcounter)”

Menggabungkan Fixed Window dengan perhitungan moving average terbobot berdasarkan jumlah request window sebelumnya.

  • Kelebihan: Menyelesaikan masalah lonjakan batas window pada Fixed Window sambil menjaga kompleksitas memori tetap $O(1)$.
  • Contoh Penggunaan:
    import "github.com/balramadan/distlimit/algorithm/slidingcounter"
    limiter, _ := distlimit.New(
    driver,
    distlimit.WithLimit(500),
    distlimit.WithWindow(1*time.Minute),
    distlimit.WithAlgorithm(slidingcounter.New()),
    )