İçeriğe atla
Cloudflare Wiki

    gez · aç · Esc kapat

    Queues

    İşleri kuyruğa alıp arka planda batch ve garantili biçimde işler.

    • DurumGenel kullanımda
    • Fiyatİşlem sayısı — her 64 KB yazma, okuma veya silme bir işlem
    • Ücretsiz katmanvar
    • Doğrulama

    Queues nedir?

    Bir isteği yanıtlarken yapılması gereken her iş, o isteğin içinde yapılmak zorunda değildir. Fatura e-postası göndermek, görüntü işlemek, dış bir API’ye bildirim atmak — bunlar kullanıcıyı bekletmeden arka planda yapılabilir.

    Cloudflare Queues bu ayrımı sağlar. Resmî tanım:

    “Send and receive messages with guaranteed delivery and no charges for egress bandwidth.”

    Kullanım amaçları resmî dokümanda dört başlıkta toplanıyor: teslimi garanti etmek, işi istekten ayırmak, Worker’dan Worker’a veri göndermek, ve veriyi tamponlayıp gruplamak.

    Nasıl çalışır?

    Dört kavram: kuyruk, üretici (producer), tüketici (consumer) ve mesaj.

    Üretici bir Worker’a kuyruk binding’i tanımlanarak kurulur. Bir kuyruğa yazan üretici sayısında sınır yoktur. Tüketici tarafında ise durum farklı:

    Teslim garantisi: en az bir kez

    Bu, Queues hakkında bilinmesi gereken en önemli şeydir.

    Queues
    TeslimEn az bir kez — nadiren birden fazla teslim olabilir
    SıralamaGaranti edilmiyor
    Tekrar engellemeSenin sorumluluğun

    Cloudflare’in önerdiği çözüm: mesajı yazarken benzersiz bir kimlik üret ve bunu veritabanı eklemelerinde birincil anahtar veya idempotency anahtarı olarak kullan.

    Gruplama (batching)

    AyarVarsayılanEn azEn çok
    max_batch_size10 mesaj1100
    max_batch_timeout5 saniye060

    İkisi birlikte çalışır; hangisi önce dolarsa batch o an teslim edilir.

    Kuyruk boşken push tüketicisi hiç çağrılmaz — maliyet doğmaz. Ama pull tüketicisi için durum farklı: “Pull-based consumers that attempt to pull from a queue, even when empty, will incur a read operation.”

    Onaylama ve yeniden deneme

    Varsayılan davranış batch’i bir bütün olarak ele alır:

    “if a batch of 10 messages is delivered, but the 8th message fails to be processed, all 10 messages will be retried and thus redelivered to your consumer in full.”

    Bu hem gereksiz iş hem gereksiz fatura demektir. Çözüm mesajları tek tek onaylamak.

    Öncelik kuralları nettir: “The first method call wins in all cases.” Bir mesaj için ack() çağırdıysan sonraki ack() veya retry() sessizce yok sayılır; tek mesaj çağrıları ackAll()/retryAll()’u ezer.

    Dead letter queue

    Varsayılan retry sayısı 3, en fazla 100. Hak bitince:

    • DLQ tanımlıysa mesaj oraya yazılır
    • Tanımlı değilse kalıcı olarak silinir

    DLQ önceden var olmak zorunda değil — belirtilen adda kuyruk yoksa otomatik oluşturulur. Tüketicisi olmayan bir DLQ’daki mesajlar 4 gün sonra silinir.

    Eşzamanlılık

    Varsayılan olarak açıktır. Cloudflare’in kendi örneği ölçeklenmeyi somutlaştırıyor: saniyede 100 mesaj yazılıyorsa ve tek tüketici 100 mesajlık batch’i 5 saniyede işliyorsa, Queues eşzamanlı çağrı sayısını yaklaşık 5’e çıkarır.

    Ölçeklenmeme sebepleri: max_concurrency 1 yapılmış, tüketici hata döndürüyor, veya bir batch hâlâ işleniyor (“Queues checks if it should autoscale consumers only after processing an entire batch”).

    Ne zaman kullanılır, ne zaman kullanılmaz

    Uygun olduğu işler

    • İstekten iş ayırma: e-posta, bildirim, dış API çağrısı
    • Yük tepesini yayma — üretici hızlı yazar, tüketici sabit hızda işler
    • Hız sınırlı bir API’ye karşı geri baskı (backpressure)
    • Yazmaları gruplayarak R2 veya dış servise toplu yazma
    • Worker’dan Worker’a veri taşıma

    Uygun olmadığı işler

    • Sıralama gerekiyorsa. Resmî olarak garanti edilmiyor, iki ayrı yerde yazıyor.
    • Exactly-once gerekiyorsa. En az bir kez teslim var; tekrarı sen engellersin.
    • Uzun, çok adımlı, kısmi ilerlemesi korunması gereken iş. Tüketici çağrısı 15 dakikayla sınırlı ve adım bazlı kontrol noktası yok. Workflows kullan.
    • Varlık bazında sıralama veya koordinasyon gerekiyorsa. Kuyruk başına tek tüketici var, partition anahtarı yok. Durable Objects kullan.
    • 24 saatten uzun gecikme gerekiyorsa. delaySeconds tavanı 24 saat.
    • Saniyede 5.000 mesajı aşan tek kuyruk. Üretici Too Many Requests alır; resmî çözüm birden çok kuyruğa yatay bölmek.
    • 25 GB’ı aşan birikme. Storage Limit Exceeded döner.

    Somut örnekler

    1. Üretici ve tüketici

    {
      "queues": {
        "producers": [{ "queue": "isler", "binding": "ISLER" }],
        "consumers": [{
          "queue": "isler",
          "max_batch_size": 10,
          "max_batch_timeout": 30,
          "max_retries": 5,
          "dead_letter_queue": "isler-dlq"
        }]
      }
    }
    export default {
      // Üretici: isteği hemen yanıtla, işi kuyruğa at
      async fetch(request, env) {
        const { siparisId } = await request.json();
        await env.ISLER.send({
          tip: "siparis-onay",
          siparisId,
          // Tekrar teslimde çift işlem yapmamak için benzersiz kimlik
          islemId: crypto.randomUUID(),
        });
        return Response.json({ alindi: true });
      },
    
      // Tüketici
      async queue(batch, env) {
        for (const mesaj of batch.messages) {
          try {
            await isle(mesaj.body, env);
            mesaj.ack();      // tek tek onayla — batch'in tamamı retry edilmesin
          } catch (h) {
            mesaj.retry();
          }
        }
      },
    };

    2. Hız sınırlı API’ye geri baskı

    Dış API 429 döndüğünde tüm batch’i geciktirerek yavaşla.

    export default {
      async queue(batch, env) {
        for (const mesaj of batch.messages) {
          const yanit = await fetch("https://api.ornek.com/gonder", {
            method: "POST",
            body: JSON.stringify(mesaj.body),
          });
    
          if (yanit.status === 429) {
            // Tüm batch'i 10 dakika geciktir — bu başarısız çağrı sayılmaz,
            // dolayısıyla otomatik ölçeklenme cezalandırılmaz
            batch.retryAll({ delaySeconds: 600 });
            return;
          }
          if (!yanit.ok) {
            mesaj.retry();
            continue;
          }
          mesaj.ack();
        }
      },
    };

    3. Üstel geri çekilme

    const TABAN_SANIYE = 30;
    
    export default {
      async queue(batch, env) {
        for (const mesaj of batch.messages) {
          try {
            await isle(mesaj.body, env);
            mesaj.ack();
          } catch {
            // attempts 1-indexlidir: 30, 900, 27000 saniye…
            mesaj.retry({ delaySeconds: TABAN_SANIYE ** mesaj.attempts });
          }
        }
      },
    };

    4. Tek tüketici, çok kuyruk

    export default {
      async queue(batch, env) {
        switch (batch.queue) {
          case "log-kuyrugu":
            await env.LOGLAR.put(`log/${Date.now()}.ndjson`,
              batch.messages.map(m => JSON.stringify(m.body)).join("\n"));
            break;
          case "eposta-kuyrugu":
            for (const m of batch.messages) await epostaGonder(m.body, env);
            break;
          default:
            console.log("bilinmeyen kuyruk", batch.queue);
        }
      },
    };

    5. Birikmeyi izleme

    const sonuc = await env.ISLER.send({ tip: "is" });
    const { backlogCount, backlogBytes, oldestMessageTimestamp } = sonuc.metadata.metrics;
    
    if (backlogCount > 100_000) {
      console.log(JSON.stringify({
        olay: "kuyruk_birikiyor",
        backlogCount,
        enEskiMesajYasiSn: (Date.now() - oldestMessageTimestamp) / 1000,
      }));
    }

    Demo 1: Batch, retry ve dead letter queue

    Adım 1 — Kuyrukları oluştur

    npx wrangler queues create isler
    npx wrangler queues create isler-dlq
    npx wrangler queues list
    Terminal — iki kuyruğun oluşturulması ve list çıktısında görünmesi

    Adım 2 — Üretici ve tüketiciyi yayına al

    npx wrangler deploy
    npx wrangler queues consumer add isler <WORKER_ADI> --dead-letter-queue=isler-dlq
    consumer add çıktısı ve panelde kuyruğun tüketici bilgisi

    Adım 3 — Batch davranışını gözle

    50 mesaj gönder, max_batch_size: 10 ile kaç çağrıda işlendiğini izle.

    Terminal — her tüketici çağrısında kaç mesaj geldiği; batch boyutunun 10'da toplandığı

    Adım 4 — Kasten hata üret

    Bir mesajı sürekli hata verecek şekilde ayarla ve retry’ları izle.

    wrangler tail — aynı mesajın attempts değeri artarak tekrar gelmesi

    Adım 5 — DLQ’ya düşüşü doğrula

    Panel veya CLI — isler-dlq kuyruğunda biriken mesaj sayısı

    Adım 6 — Tek tek onaylamanın farkı

    msg.ack() olmadan ve varken aynı testi çalıştır.

    İki wrangler tail çıktısı yan yana — ack'siz sürümde 10 mesajın tamamının tekrar geldiği, ack'li sürümde yalnızca hatalı olanın geldiği

    Demo 2: Hız sınırlı API’ye karşı geri baskı

    Adım 1 — Hız sınırlı bir test API’si kur

    Basit bir Worker veya yerel servis — belirli bir hızın üstünde 429 döndürüyor

    Adım 2 — Geri baskısız hâli çalıştır

    Log çıktısı — çok sayıda 429 yanıtı ve boşa harcanan retry'lar

    Adım 3 — retryAll ile geri çekil

    Log çıktısı — 429 alındığında batch'in geciktirilmesi ve 429 sayısının düşmesi

    Adım 4 — Eşzamanlılığın davranışını gözle

    Queues metrik ekranı — eşzamanlı tüketici çağrısı sayısının yük altında artması

    Adım 5 — Kuyruğu duraklat

    npx wrangler queues pause-delivery isler
    npx wrangler queues resume-delivery isler
    Metrik ekranı — teslim durdurulduğunda backlog'un artışı, devam ettirildiğinde erimesi

    Ölçüm

    ÖlçütGeri baskısızretryAll ile
    Toplam 429 yanıtı
    Toplam işlem (fatura) sayısı
    Tüm mesajların işlenme süresi
    Eşzamanlı tüketici tepe değeri

    Fiyatlandırma

    Rakamlar 1 Eylül 2026’da resmî dokümandan doğrulanmıştır.

    ÜcretsizÜcretli
    Standart işlemGünde 10.000 dahilAyda 1 milyon dahil, sonrası milyon başına 0,40 USD
    Mesaj saklama24 saat (uzatılamaz)Varsayılan 4 gün, en fazla 14 gün

    İşlem nasıl sayılır:

    • Yazılan, okunan veya silinen her 64 KB bir işlemdir
    • 127 KB’lık bir mesaj yazılırken, okunurken ve silinirken ikişer işlem sayar
    • İşlemler batch başına değil mesaj başına sayılır — 10 mesajlık bir batch 10 yazma, 10 okuma, 10 silme işlemi doğurur
    • Normalde bir mesaj 3 işlem eder: yazma + okuma + silme
    • Her retry ek bir okuma yazar
    • Egress veya bant genişliği ücreti yoktur

    Resmî formül:

    ((mesaj sayısı × 3) − 1.000.000) / 1.000.000 × 0,40 USD

    Cloudflare’in kendi örnekleri

    SenaryoFaturalanan işlemAylık
    Günde 1 milyon mesaj (64 KB altı), 30 gün89.000.00035,60 USD
    Ayda 100 milyon mesaj, her biri ~127 KB599.000.000239,60 USD

    İkinci satır 64 KB kuralının etkisini gösteriyor: mesaj boyutu iki katına çıkınca işlem sayısı da ikiye katlanıyor.

    Kuyruğu boşaltmak (purge) kaç mesaj silinirse silinsin tek işlem sayılır.

    Tüketicinin harcadığı CPU ve istek ayrıca Workers fiyatlandırmasına tabidir.

    Limitler

    ÖzellikSınır
    Hesap başına kuyruk10.000
    Mesaj boyutu128 KB
    Mesaj retry sayısı100
    Tüketici batch boyutu100 mesaj
    sendBatch başına mesaj100 (veya toplam 256 KB)
    Batch bekleme süresi60 saniye
    Kuyruk başına throughputsaniyede 5.000 mesaj
    Mesaj saklama14 güne kadar (ücretsizde 24 saat sabit)
    Kuyruk başına birikme25 GB
    Eşzamanlı tüketici çağrısı250 (yalnızca push)
    Tüketici duvar saati15 dakika
    Tüketici CPU süresi5 dakikaya kadar ayarlanabilir
    visibilityTimeout (pull)12 saat
    delaySeconds24 saat

    Aşım davranışları: throughput aşılınca send() ve sendBatch() Too Many Requests fırlatır; birikme sınırı aşılınca Storage Limit Exceeded döner.

    Lisanslama ve hukuki çerçeve

    Queues tescilli bir hizmettir; Cloudflare Hizmet Şartları kapsamındadır.

    Mesaj içeriği Cloudflare’de saklanır — varsayılan 4 gün, en fazla 14 gün. Kuyruğa yazdığın her şey bu süre boyunca Cloudflare’in altyapısında durur. Kişisel veri taşıyorsan:

    • Mesaj gövdesine ham kişisel veri yerine referans (kimlik) yazmayı değerlendir
    • Saklama süresini ihtiyacın kadar kısalt
    • DLQ’daki mesajları da veri envanterine dahil et — orada 4 gün daha durabilirler

    Yargı bölgesi kısıtı Queues için tanımlı değildir.

    Sık yapılan hatalar

    Sıralama varsaymak. Dokümanda iki kez garanti edilmediği yazıyor.

    Exactly-once varsaymak. Tekrar teslim olabilir; idempotency anahtarı kullan.

    batch.messages.forEach() içinde asenkron iş yapmak. Beklemez. for...of veya Promise.all(map(...)) kullan.

    Tek tek onaylamamak. Batch’in 8. mesajı hata verirse 10’u birden tekrar teslim edilir ve retry başına 10 okuma işlemi faturalanır.

    Kritik yazmayı ctx.waitUntil() içine koymak. Resmî uyarı: “because waitUntil() is non-blocking, any errors raised from the send() or sendBatch() methods on a queue will be implicitly ignored.”

    max_concurrency: 1 verip ölçeklenmemesine şaşırmak. Cloudflare’in kendi “neden ölçeklenmiyor” listesinin ilk maddesi.

    Mesaj başına 1 işlem bütçelemek. Normalde 3’tür, her retry bir okuma daha ekler.

    Pull tüketicisiyle boş kuyruğu yoklamak. Boş çekim bile okuma işlemi maliyeti doğurur.

    CLI ile tüketiciyi kaldırıp yapılandırmayı silmemek. Resmî uyarı: sonraki deploy’lar çakışan tüketici yapılandırması yüzünden başarısız olur.

    Pull tüketicisine v8 içerik tipi göndermek. “Pull-based consumers cannot decode the v8 content type as it is specific to the Workers runtime.”

    Sıkça sorulan sorular

    Teslim garantisi tam olarak nedir?
    En az bir kez (at-least-once). Resmî ifade: “Queues provides at least once delivery by default in order to optimize for reliability… messages are guaranteed to be delivered at least once, and in rare occasions, may be delivered more than once.” Yani exactly-once değil. Tekrarları kendin engellemelisin — Cloudflare'in önerisi mesaja benzersiz bir kimlik yazıp bunu veritabanında birincil anahtar veya idempotency anahtarı olarak kullanmak.
    Mesajlar sıralı mı geliyor?
    Hayır, ve bu dokümanda iki ayrı yerde yazıyor: “Queues does not guarantee that messages will be delivered to a consumer in the same order in which they are published.” Batch içindeki sıra için de: “Ordering of messages is best effort.” FIFO gerektiren bir işin varsa Queues doğru araç değildir.
    Bir kuyruğa kaç tüketici bağlayabilirim?
    Bir tane, ve tek tip. Resmî ifade: “each queue can only have one active consumer. This allows Cloudflare Queues to achieve at least once delivery and minimize the risk of duplicate messages.” Push (Worker) ve pull (HTTP) tüketicileri aynı kuyrukta birlikte kullanılamaz. Tersi serbest: bir tüketici Worker birden çok kuyruğa hizmet edebilir, batch.queue hangi kuyruktan geldiğini söyler.
    Batch'teki bir mesaj hata verirse ne olur?
    Varsayılan davranış hepsi ya da hiçbiri: “if a batch of 10 messages is delivered, but the 8th message fails to be processed, all 10 messages will be retried.” Bu hem tekrar teslim hem de fatura demektir — her retry batch'teki her mesaj için bir okuma işlemi yazar. Çözüm: başarılı mesajları tek tek msg.ack() ile onayla.
    Retry hakkı bitince mesaj ne oluyor?
    Dead letter queue tanımlıysa oraya yazılır; tanımlı değilse kalıcı olarak silinir. Resmî ifade: “Without a DLQ configured, messages that reach the retry limit are deleted permanently.” DLQ'nun önceden var olması gerekmiyor: “If there is no queue with the specified name, it will be created automatically.” Tüketicisi olmayan bir DLQ'daki mesajlar 4 gün sonra silinir.
    Mesajı ne kadar geciktirebilirim?
    En fazla 24 saat (delaySeconds, 0–86400). Gönderirken veya retry ederken verilebilir. Mesaj bazlı ayar kuyruk bazlı ayarı ezer; delaySeconds: 0 vermek kuyruk seviyesindeki gecikmeyi iptal eder. Daha uzun beklemeler için Workflows'un step.sleep'ine bak — orada sınır 365 gün.
    Eşzamanlılığı açmam gerekiyor mu?
    Hayır, zaten açık: “By default, all queues have concurrency enabled.” Cloudflare max_concurrency'yi hiç ayarlamamanı öneriyor — sabit bir sayı verirsen Cloudflare zamanla üst sınırı yükseltse bile senin tüketicin o rakamda takılı kalır. Ayrıca maliyeti artırmaz: “the effective overall cost is the same… Enabling concurrency simply brings those costs forward.”
    retry() çağırmak otomatik ölçeklenmemi bozar mı?
    Hayır. Resmî ifade: “Retrying messages with retry() or calling retryAll() on a batch will not count as a failed invocation.” Başarısız sayılan şey, queue() handler'ının yakalanmamış bir istisna fırlatmasıdır. Yani hız sınırına takıldığında retryAll({ delaySeconds }) ile geri çekilmek ölçeklenmeyi cezalandırmaz.
    Cloudflare dışından tüketebilir miyim?
    Evet, HTTP pull tüketicisiyle — herhangi bir dilden. API token'ının hem queues_read hem queues_write iznine sahip olması gerekir (onaylama işlemi de yazma sayılır). Önemli kısıt: “Queues does not hold an open connection (often referred to as 'long polling') if there are no messages to deliver.” Yani boş kuyruğu yoklamak bile bir okuma işlemi maliyeti doğurur.
    Bir mesaj kaç işlem sayılıyor?
    Normalde üç: bir yazma, bir okuma, bir silme. Resmî formül: ((mesaj sayısı × 3) − 1.000.000) / 1.000.000 × 0,40 USD. Dikkat edilecek üç nokta: her 64 KB ayrı bir işlem sayılır (127 KB'lık mesaj iki işlem), her retry ek bir okuma yazar, ve işlemler batch başına değil mesaj başına sayılır.
    Ücretsiz planda saklama süresi ayarlanabilir mi?
    Yukarı doğru hayır. Fiyat tablosu ücretsiz plan için 24 saat ve “non-configurable” diyor. Ancak wrangler queues create --message-retention-period-secs yardımı “Must be between 60 and 86400 if on free tier” diyor — yani kısaltabilirsin, uzatamazsın. Ücretli planda varsayılan 4 gün, en fazla 14 gün.
    Queues mu, Workflows mu, Durable Object alarmı mı?
    Queues: çok sayıda bağımsız, birbirinin aynı iş parçası; yük tepesini yayma. Workflows: adımları birbirine bağımlı, kısmi ilerlemesi korunması gereken süreç; adım başına duvar saati sınırsız. DO alarmı: state'i zaten bir Durable Object'te duran ve kendini uyandırması gereken iş. Duvar saati sınırları: Queues tüketicisi 15 dakika, DO alarmı 15 dakika, Workflows adımı sınırsız.
    Kuyruğu geçici olarak durdurabilir miyim?
    Evet: wrangler queues pause-delivery. Mesajlar gelmeye ve saklama süresine doğru yaşlanmaya devam eder, yalnızca teslim durur. Pull tüketicileri bu sırada HTTP 409 ve queue_delivery_paused alır. Olay müdahalesinde arkadaki servisi korumak için kullanışlıdır.

    İlgili servisler

    • WorkersJavaScript/TypeScript/Python kodunu Cloudflare’in 330+ şehirdeki sunucularında, sunucu yönetmeden çalıştırır.
    • WorkflowsSaatler veya günler süren çok adımlı işleri, adım bazında kalıcı state ve otomatik retry ile yürütür.
    • Durable ObjectsHer nesnenin tek bir instance’ı olan, state tutan compute; sohbet odası, oyun oturumu, sayaç gibi işler için.
    • R2S3 uyumlu object storage — çıkış (egress) trafiği ücretsiz.
    • D1Workers’a bağlanan serverless SQLite veritabanı.

    Bu sayfadaki fiyat ve özellik bilgileri 1 Eylül 2026 tarihinde Cloudflare’in resmî kaynaklarından doğrulanmıştır. Cloudflare fiyatlandırmasını önceden haber vermeden değiştirebilir; bağlayıcı bilgi içinresmî sayfaya bakın.

    Hata bildir

    Yanlış bir rakam, eskimiş bir bilgi veya bozuk bir bağlantı mı buldun? Bildir, kaynağıyla birlikte kontrol edelim.