API'lerinizi korumak ve kaynak kullanımını dengelemek için rate limiting vazgeçilmezdir. Ancak doğru algoritmayı seçmek, hem kullanıcı deneyimi hem de güvenlik açısından kritik öneme sahiptir. En sık kullanılan iki yaklaşım olan Fixed Window ve Token Bucket, farklı özellikleriyle öne çıkar. Bu yazıda her iki algoritmayı detaylı bir şekilde karşılaştıracak ve ihtiyacınıza en uygun olanı seçmenize yardımcı olacağız.
Fixed Window (Sabit Pencere) Algoritması Nedir?
Fixed Window, zamanı eşit aralıklarla bölen ve her pencerede belirli bir istek sayısına izin veren basit bir algoritmadır. Örneğin, dakikada 100 istek limiti koyduğunuzda, her dakika başında sayaç sıfırlanır ve o dakika içinde en fazla 100 istek işlenir. Bu yaklaşım, uygulaması kolay ve bellek açısından hafif olmasına rağmen, pencere sınırlarında patlama (burst) yaşanmasına neden olabilir.
Fixed Window'ın Avantajları
- Basitlik: Kodlaması ve anlaşılması çok kolaydır. Redis'te basit bir sayaç + TTL ile uygulanabilir.
- Düşük bellek kullanımı: Sadece bir sayaç ve pencere başlangıç zamanı tutulur.
- Hızlı hesaplama: Her istekte sadece sayaç kontrolü yapılır.
Fixed Window'ın Dezavantajları
- Pencere sınırı patlamaları: Bir pencerenin sonunda ve diğerinin başında kullanıcılar iki kat limite ulaşabilir (örneğin, 59. saniyede 100 istek, 60. saniyede 100 istek = 200 istek).
- Adaletsizlik: Tüm kullanıcılar aynı pencere diliminde limiti doldurursa, eşit dağılım bozulur.
Token Bucket (Jeton Kovası) Algoritması Nedir?
Token Bucket, sabit bir oranda jeton üreten ve bu jetonları depolayan bir kova metaforuyla çalışır. Her istek bir jeton tüketir; kovada jeton yoksa istek reddedilir. Bu algoritma, uzun vadeli ortalama hızı sınırlarken kısa süreli patlamalara izin verir. Özellikle trafik dalgalanmalarının olduğu sistemlerde esneklik sağlar.
Token Bucket'ın Avantajları
- Patlama toleransı: Kova boyutu kadar anlık patlamalara izin verir, böylece normal kullanıcı deneyimini bozmaz.
- Daha adil dağılım: Jeton doldurma hızı sayesinde uzun vadede kullanıcılar arasında eşitlik sağlanır.
- Esneklik: Parametreler (doldurma hızı, kova boyutu) kolayca ayarlanabilir.
Token Bucket'ın Dezavantajları
- Karmaşıklık: Uygulaması Fixed Window'a göre biraz daha zordur; zamanlayıcı veya sürekli hesaplama gerektirir.
- Bellek kullanımı: Her kullanıcı için ayrı kova bilgisi tutulması gerekebilir.
Karşılaştırma Tablosu
| Özellik | Fixed Window | Token Bucket |
|---|---|---|
| Uygulama zorluğu | Düşük | Orta |
| Bellek ihtiyacı | Düşük | Düşük-Orta (kullanıcı sayısına bağlı) |
| Patlama toleransı | Yok | Var (kova boyutu kadar) |
| Pencere sınırı sorunu | Var | Yok |
| Uzun vadeli adalet | Düşük | Yüksek |
| Gerçek zamanlı uygunluk | Yüksek | Orta (hesaplama gecikmesi olabilir) |
Hangi Senaryoda Hangi Algoritmayı Seçmelisiniz?
Fixed Window'ı Tercih Edin Eğer:
- Uygulamanız çok basit ve düşük trafikli ise.
- Patlama toleransı kritik değilse (örneğin, dosya yükleme gibi yoğun işlem yoksa).
- Hızlı prototip veya MVP aşamasındaysanız.
Token Bucket'ı Tercih Edin Eğer:
- Kullanıcı deneyimi ön planda ve ani patlamalara izin vermek istiyorsanız (örneğin, sosyal medya API'si).
- API'niz düzensiz trafik alıyorsa (gece-gündüz farkı, kampanya dönemleri).
- Uzun vadede adil bir kullanım kotası sağlamak istiyorsanız.
Pratik Uygulama Önerileri
Her iki algoritmayı da REST API Rate Limiting'de Algoritma Seçimi yazımızda daha ayrıntılı ele almıştık. Burada kısa kod örnekleriyle pekiştirelim.
Fixed Window Redis ile (Node.js)
const redis = require('redis');
const client = redis.createClient();
async function fixedWindow(userId, limit, windowSeconds) {
const key = `rate:${userId}:${Math.floor(Date.now()/1000/windowSeconds)}`;
const count = await client.incr(key);
if (count === 1) await client.expire(key, windowSeconds);
return count <= limit;
}
Token Bucket Redis ile (Node.js)
async function tokenBucket(userId, rate, capacity) {
const now = Date.now() / 1000;
const key = `bucket:${userId}`;
const bucket = await client.hGetAll(key);
let tokens = parseFloat(bucket.tokens) || capacity;
let lastRefill = parseFloat(bucket.lastRefill) || now;
const elapsed = now - lastRefill;
tokens = Math.min(capacity, tokens + elapsed * rate);
if (tokens < 1) return false;
tokens -= 1;
await client.hSet(key, 'tokens', tokens, 'lastRefill', now);
return true;
}
Sık Yapılan Hatalar ve Dikkat Edilmesi Gerekenler
- Yanlış parametre seçimi: Kova boyutu çok küçük olursa patlama toleransı kaybolur; çok büyük olursa rate limiting anlamsızlaşır. Ortalama trafiğinizi analiz edin.
- Dağıtık sistemlerde atomik işlemler: Redis'te INCR veya Lua script kullanın, race condition'lardan kaçının.
- Gerçek zamanlı güncelleme: Token Bucket'ta zaman periyodik olarak değil, her istekte güncellenir; bu doğru çalışma için kritiktir.
- Hata kodlarını doğru kullanın: Rate limiting aşıldığında 429 Too Many Requests dönün ve Retry-After header'ı ekleyin. Detaylar için REST API Hata Yönetimi yazımıza göz atın.
Önbellekleme stratejileriyle rate limiting'i desteklemek de performansı artırabilir. Bu konuda API Caching Best Practices rehberimizi inceleyebilirsiniz.
Sonuç
Fixed Window ve Token Bucket arasındaki seçim, API'nizin trafik desenine ve iş gereksinimlerine bağlıdır. Basit ve düşük trafikli sistemlerde Fixed Window yeterli olurken, kullanıcı deneyimini önemseyen ve patlamalara izin vermek isteyen sistemlerde Token Bucket daha uygundur. Her iki algoritmayı da test ederek kendi senaryonuzda en iyi sonucu alın.
Sık Sorulan Sorular
Fixed Window algoritması neden patlama sorununa yol açar?
Pencere sınırlarında sayaç sıfırlandığı için kullanıcı bir pencerenin sonunda ve diğerinin başında limiti doldurarak iki kat istek gönderebilir. Bu, özellikle kesintisiz hizmet gereken durumlarda sorun yaratır.
Token Bucket'ın kova boyutu nasıl belirlenmeli?
Kova boyutu, izin vermek istediğiniz maksimum anlık patlama büyüklüğüdür. Genellikle ortalama hızın 2-5 katı arasında seçilir; çok büyük olursa rate limiting amacına ulaşamaz.
Hangi durumda Fixed Window yerine Token Bucket tercih edilmelidir?
Kullanıcı deneyiminin önemli olduğu, ani trafik artışlarının yaşandığı veya adil bir kullanım kotası sağlamak istendiğinde Token Bucket daha uygundur. Örneğin, video akışı veya sosyal medya API'leri.
Rate limiting için Redis kullanmak zorunlu mu?
Hayır, ancak Redis gibi hızlı ve atomik işlemleri destekleyen bir veri deposu önerilir. Küçük ölçekli uygulamalarda bellekte (in-memory) da uygulanabilir, ancak dağıtık sistemlerde Redis yaygındır.






