Botunuz bir anda yavaşladı, mesajlar gecikmeyle gidiyor ya da loglarda 429 Too Many Requests satırları birikiyor mu? Bu, Discord API'nin rate limit (hız sınırı) mekanizmasının devreye girdiği anlamına gelir. Discord spam, kötüye kullanım ve aşırı yükü önlemek için hem her uç nokta (route) bazında hem de bot genelinde istek sınırları uygular.

Bu rehberde Discord rate limit sisteminin nasıl çalıştığını, X-RateLimit-* başlıklarını, 429 yanıtının gövdesini, saniyede 50 isteklik global sınırı, sık gözden kaçan geçersiz istek sınırını ve Cloudflare yasağını, gateway tarafındaki sınırları ve discord.js ile discord.py'nin bunu nasıl yönettiğini anlatıyoruz. Genel API tasarımı açısından konuya bakmak isterseniz API rate limiting stratejileri yazımız da işinize yarar.

Discord rate limit nasıl çalışır?

Discord rate limit nasıl çalışır? Per-route (uç nokta bazlı) sınırlar, Global sınır

Discord sınırları isteği yapan kimliğe göre uygular; bot için bu kimlik bot token'ıdır. İki ana sınır türü vardır:

  • Per-route (uç nokta bazlı) sınırlar: birçok uç noktanın kendi sınırı vardır ve sınır HTTP yöntemini (GET, POST, PUT, DELETE) de içerebilir. Bazı benzer uç noktalar aynı sınırı paylaşır; bu durum X-RateLimit-Bucket başlığıyla belirtilir.
  • Global sınır: botun yaptığı toplam istek sayısına uygulanır ve uç nokta sınırlarından bağımsızdır.

Uç nokta sınırları yoldaki üst düzey kaynağı da hesaba katar. Belgeye göre üst düzey kaynaklar şimdilik kanallar (channel_id), sunucular (guild_id) ve webhook'lardır (webhook_id veya webhook_id + webhook_token). Yani /channels/1234 için sınıra takılsanız bile /channels/9876 çağrısını sorunsuz yapabilirsiniz; her kanalın kovası (bucket) ayrı hesaplanır.

X-RateLimit başlıkları

Çoğu API yanıtında Discord, karşılaştığınız sınırı anlatan isteğe bağlı başlıklar döndürür:

BaşlıkAnlamı
X-RateLimit-LimitBu kovada yapılabilecek istek sayısı
X-RateLimit-RemainingKalan istek sayısı
X-RateLimit-ResetSınırın sıfırlanacağı an (Unix epoch, saniye)
X-RateLimit-Reset-AfterKovanın sıfırlanmasına kalan süre (saniye, ondalıklı olabilir)
X-RateLimit-BucketSınırı tanımlayan benzersiz metin; paylaşılan sınırları gruplamak için kullanın
X-RateLimit-GlobalYalnızca 429 yanıtında; global sınıra takıldıysanız gelir
X-RateLimit-ScopeYalnızca 429 yanıtında; user, global veya shared değerini alır

Scope değerinin anlamı: user bot veya kullanıcı başına sınır, global bot veya kullanıcı başına global sınır, shared ise kaynak başına (örneğin kalabalık bir kanal) sınırdır.

429 hatası ve retry_after

429 hatası ve retry_after: message, retry_after, global, code

Bir sınırı aştığınızda API HTTP 429 durum kodu ve JSON gövdesi döner. Ne zaman tekrar deneyeceğinizi Retry-After başlığından ya da gövdedeki retry_after alanından öğrenmelisiniz.

AlanTipAçıklama
messagestringSınıra takıldığınızı bildiren mesaj
retry_afterfloatYeni istek göndermeden önce beklenecek saniye
globalbooleanGlobal sınıra mı takıldığınızı gösterir
codeinteger (isteğe bağlı)Bazı sınırlar için JSON hata kodu
http
HTTP/1.1 429 TOO MANY REQUESTS
Content-Type: application/json
Retry-After: 65
X-RateLimit-Limit: 10
X-RateLimit-Remaining: 0
X-RateLimit-Reset-After: 64.57
X-RateLimit-Bucket: abcd1234
X-RateLimit-Scope: user

{
  "message": "You are being rate limited.",
  "retry_after": 64.57,
  "global": false
}

429 yanıtlarında normal uç nokta başlıkları da gönderilir. Global sınırda gövdede "global": true ve X-RateLimit-Global: true başlığı bulunur.

Global sınır: saniyede 50 istek

Tüm botlar Discord API'ye saniyede en fazla 50 istek gönderebilir. Authorization başlığı yoksa sınır IP adresine uygulanır. Bu, uç nokta sınırlarından bağımsızdır. Resmî belge, bot yeterince büyüdüğünde normal çalışma sırasında bile bu sınırın altında kalmanın imkânsız olabileceğini, böyle durumlarda dis.gd/rate-limit üzerinden destekle iletişime geçip daha yüksek global sınıra uygun olup olmadığınızı sorabileceğinizi belirtir.

Geçersiz istek sınırı ve Cloudflare yasağı

En çok gözden kaçan sınır budur. Çok sayıda geçersiz HTTP isteği yapan IP adresleri Discord API'ye erişimden otomatik ve geçici olarak engellenir. Güncel sınır 10 dakikada 10.000 geçersiz istektir. Geçersiz istek; 401, 403 veya 429 durum kodu dönen istek demektir. Tek istisna: X-RateLimit-Scope: shared ile dönen 429 yanıtları size karşı sayılmaz.

Discord'a göre botunuz arada bir Cloudflare yasağı yiyorsa bunun sebebi büyük ihtimalle global sınır değil, düzgün yönetilmemiş bir hata patlamasıdır. Önlemek için:

  • 401'den kaçının: geçerli token gönderin ve token geçersizleştiği anda istek yapmayı durdurun. Sızan token'ı sıfırladıysanız eski token'la döngüye girmeyin.
  • 403'ten kaçının: istek atmadan önce rol ve kanal izinlerini kontrol edin; yetkiniz olmayan işlemi tekrar tekrar denemeyin. İzin mantığı için bot izinleri ve rol hiyerarşisi.
  • 429'dan kaçının: başlıkları izleyin, tükenmiş bir kovaya sıfırlanmadan istek göndermeyin.
  • 404 veren webhook'u bırakın: belgeye göre 404 dönen bir webhook'u tekrar tekrar kullanmak da geçici kısıtlamaya yol açar.

10 dakikada 10.000 istek, sürekli saniyede yaklaşık 16-17 isteğe denk gelir. Bu hacme ulaşabilecek uygulamaların geçersiz istek oranını loglayıp izlemesi önerilir. Ayrıca HTTP API kullanan istemcilerin DiscordBot ($url, $versionNumber) biçiminde geçerli bir User-Agent göndermesi gerekir; aksi halde istekler Cloudflare tarafından engellenebilir (JSON kodu 40333). Cloudflare'in genel işleyişi için Cloudflare nedir yazısına bakabilirsiniz.

Gateway tarafındaki sınırlar

Gateway tarafındaki sınırlar: Bağlantı başına 60 saniyede 120 gateway olayı gönderebilirsiniz (ortalama..., Eş zamanlı Identify sayısı, max_concurrency değeriyle 5 saniyelik...

HTTP sınırlarının yanında WebSocket bağlantısının da kendi sınırları vardır:

  • Bağlantı başına 60 saniyede 120 gateway olayı gönderebilirsiniz (ortalama saniyede 2). Aşan uygulamanın bağlantısı hemen kesilir (kapanış kodu 4008); tekrarlayanların API erişimi kaldırılabilir.
  • Eş zamanlı Identify sayısı, max_concurrency değeriyle 5 saniyelik pencerelerde sınırlıdır; aşarsanız Invalid Session (opcode 9) alırsınız. Ayrıntılar Discord sharding yazısında.
  • Bir sunucunun tüm üyelerini istemek (Request Guild Members, limit 0 ve boş query) bot başına her sunucu için 30 saniyede 1 istekle sınırlıdır. Aşan istek RATE_LIMITED olayıyla yanıtlanır. discord.js'teki "Request with opcode 8 was rate limited" hatası bunu anlatır.

discord.js ve discord.py rate limit'i nasıl yönetir?

İyi haber: popüler kütüphaneler REST isteklerini kendi kuyruklarından geçirir, başlıkları okur ve 429 durumunda bekleyip tekrar dener. Yani kütüphanenin metodlarını kullandığınız sürece çoğu zaman elle bir şey yapmanız gerekmez. Sorun genellikle kütüphaneyi atlayıp kendi fetch döngünüzü kurduğunuzda ya da bir döngü içinde yüzlerce istek ürettiğinizde başlar.

discord.js

discord.js v14'te rate limit olayı rateLimited adını aldı ve client.rest üzerine taşındı. Bu olayı dinleyerek hangi uç noktaların sınıra takıldığını loglayabilirsiniz:

javascript
const { Client, GatewayIntentBits } = require('discord.js');

const client = new Client({ intents: [GatewayIntentBits.Guilds] });

client.rest.on('rateLimited', (info) => {
  console.warn('Rate limit:', info);
});

client.login(process.env.DISCORD_TOKEN);

discord.py

discord.py belgesi, kütüphanenin 429'ları önleyen bir rate limit yönetimi içerdiğini belirtir; bekleme süresini Discord'un yanıtına göre hesaplar. Bir istek başarısız olursa discord.HTTPException (ve alt sınıfları Forbidden, NotFound) fırlatılır; API referansında ayrıca RateLimited istisnası tanımlıdır.

Kütüphanesiz istek atıyorsanız

Cloudflare Workers gibi ortamlarda doğrudan HTTP kullanıyorsanız 429'u kendiniz yönetmelisiniz. Aşağıdaki örnek retry_after kadar bekleyip sınırlı sayıda tekrar dener:

javascript
async function discordIstek(url, options, deneme = 3) {
  for (let i = 0; i < deneme; i++) {
    const res = await fetch(url, {
      ...options,
      headers: {
        Authorization: `Bot ${process.env.DISCORD_TOKEN}`,
        'User-Agent': 'DiscordBot (https://ornek.com, 1.0.0)',
        'Content-Type': 'application/json',
        ...options.headers,
      },
    });
    if (res.status !== 429) return res;
    const body = await res.json();
    await new Promise((r) => setTimeout(r, body.retry_after * 1000));
  }
  throw new Error('Rate limit nedeniyle istek tamamlanamadı');
}

HTTP tabanlı botlar için tam bir örnek Discord HTTP interactions ve Cloudflare Workers yazısında yer alıyor.

Rate limit'e takılmamak için pratik ipuçları

  • Toplu uç noktaları kullanın: mesajları tek tek silmek yerine Bulk Delete kullanın. Bu uç nokta en az 2, en fazla 100 mesaj alır ve 2 haftadan eski mesajları silmez.
  • Tek mesajı düzenleyin: ilerleme bildirmek için sürekli yeni mesaj atmak yerine aynı mesajı aralıklarla düzenleyin.
  • Önbelleği kullanın: elinizde olan veriyi tekrar tekrar API'den çekmeyin. Kalıcı veriler için Redis veya SQLite gibi bir depolama kullanabilirsiniz.
  • Toplu işleri kuyruğa alın: çok sayıda kullanıcıya rol verme veya DM gönderme gibi işleri zamana yayın.
  • Hata döngülerini kesin: 403 alan bir işlemi aynı parametrelerle sonsuza kadar tekrar etmeyin; hatayı loglayıp durun.
  • 401/403/429 sayısını izleyin: bu üç kodun toplamı geçersiz istek sınırına sayılır.
  • Komut kaydını her açılışta yapmayın: slash komutlarını yalnızca değiştiklerinde kaydedin; günlük komut oluşturma sınırı vardır (JSON kodu 30034, günde 200).

Sık Sorulan Sorular

Discord rate limit ne kadar sürer?

Sabit bir süre yoktur. Bekleyeceğiniz süre her 429 yanıtındaki retry_after alanında ve Retry-After başlığında yazar. Cloudflare kaynaklı geçici IP yasağı ise ayrı bir durumdur ve geçersiz istek sınırının aşılmasından kaynaklanır.

429 alırsam botum banlanır mı?

Tek tük 429 normaldir ve kütüphaneler bunu yönetir. Ancak 429'lar 401 ve 403'lerle birlikte geçersiz istek sayılır; 10 dakikada 10.000'i aşarsanız IP'niz geçici olarak engellenir. Gateway'de tekrarlanan sınır aşımları için Discord API erişiminin kaldırılabileceğini belirtir.

Aynı sunucuda birden fazla bot çalıştırmak sınırı artırır mı?

Sınırlar token başına uygulanır, ancak global sınır yetkilendirme olmayan isteklerde IP'ye uygulanır ve geçersiz istek sınırı IP bazlıdır. Aynı IP'den çalışan botların hatalı istekleri birbirini etkileyebilir.

Global sınırı aşıyor muyum, nasıl anlarım?

429 yanıtında X-RateLimit-Global: true başlığı ya da gövdede "global": true varsa global sınıra takılmışsınızdır. X-RateLimit-Scope başlığı da sınırın türünü söyler.

Marka adları sahiplerine aittir. Bu yazı bağımsız bir teknik rehberdir; adı geçen kuruluşlarla bayilik veya ortaklık ilişkisi bulunduğu anlamına gelmez.

İlgili içerikler: Discord API hata kodları · Discord sharding nedir · Etkileşim başarısız oldu hatası · HTTP interactions ve Cloudflare Workers · API rate limiting stratejileri · Discord botunu 7/24 aktif tutma