İçeriğe atla
Cloudflare Wiki

    gez · aç · Esc kapat

    Workflows

    Saatler 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.

    • DurumGenel kullanımda
    • Fiyatİstek + CPU süresi + adım sayısı + depolama
    • Ücretsiz katmanvar
    • Doğrulama

    Workflows nedir?

    Çok adımlı bir iş süreci düşün: kartı çek → stoğu ayır → makbuz gönder → 3 gün bekle → yorum iste. Bu sürecin çökmelere, deploy’lara, üçüncü taraf API kesintilerine ve günlerce süren beklemelere dayanması gerekir.

    Workflows olmadan bunu elle yazarsın: bir durum tablosu, bir retry/backoff işçisi, bir zamanlayıcı, dead-letter yönetimi ve idempotency anahtarları. Workflows bunu tersine çevirir — programın kendisi durum makinesidir. Her await step.do() bir kontrol noktasıdır.

    Cloudflare’in kendi tanımı:

    “The term ‘Durable Execution’ is widely used to describe this programming model. ‘Durable’ describes the ability of the program to implicitly persist state without you having to manually write to an external store or serialize program state.”

    Nasıl çalışır?

    Durable execution modeli

    Workflow, WorkflowEntrypoint sınıfını genişletir ve bir run(event, step) metodu içerir. Her step.do(ad, geriCagirim) çağrısı geri çağırımı çalıştırır ve dönüş değerini kalıcı olarak saklar.

    Örnek kesintiye uğrarsa (çökme, deploy, retry, hibernation) run() baştan tekrar çalışır — ama tamamlanmış her adım kodu yeniden çalıştırmak yerine önbellekteki değerini döndürür.

    Adımlar ve serileştirme

    Adım dönüş değerleri structured-clone ile serileştirilir ve 1 MiB ile sınırlıdır. Function veya Symbol içeren nesneler ve dairesel referanslar serileştirilemez.

    Büyük ikili çıktı için ReadableStream<Uint8Array> döndürülebilir; akış taze ve kilitsiz olmalı, parçalar 16 MB altında kalmalıdır.

    Retry

    Varsayılanlar:

    const varsayilan = {
      retries: { limit: 5, delay: 10000, backoff: "exponential" },
      timeout: "10 minutes",
    };

    backoff değerleri: "constant", "linear", "exponential". timeout deneme başınadır — her retry için yeniden sayılır. Adım başına en fazla 10.000 retry.

    Kalıcı hatalarda retry’ı durdurmak için:

    import { NonRetryableError } from "cloudflare:workflows";
    throw new NonRetryableError("kart reddedildi");

    Rollback — saga deseni

    Workflows telafi işlemlerini yerleşik olarak destekler. Bir adım rollback handler’ı kaydeder; workflow sonradan başarısız olursa handler’lar ters sırada çalışır.

    await step.do("kartı çek",
      async () => {
        const cekim = await kartCek();
        return { cekimId: cekim.id };
      },
      {
        rollback: async ({ ctx, output, error }) => {
          await iadeEt(output.cekimId, { sebep: `${ctx.step.name}: ${error.message}` });
        },
        rollbackConfig: { retries: { limit: 3, delay: "30 seconds", backoff: "linear" } },
      },
    );

    Rollback handler’ları ve retry’lar adım sayısına dahil değildir.

    Uyuma ve olay bekleme

    await step.sleep("biraz bekle", "1 hour");
    await step.sleepUntil("belirli ana kadar bekle", Date.parse("24 Oct 2026 13:00:00 UTC"));

    Kabul edilen birimler: second, minute, hour, day, week, month, year. En fazla 365 gün.

    Uyuyan örnekler waiting durumuna geçer ve eşzamanlılık kotası tüketmez. Resmî ifade: “you can have millions of Workflow instances sleeping or waiting for events simultaneously, as only actively running instances count toward the concurrent instance limit.”

    Dış olay beklemek için:

    const karar = await step.waitForEvent("gözden geçirenin kararını bekle", {
      type: "review-decision",   // 'event' DEĞİL — resmî ana sayfa örneği hatalı
      timeout: "7 days",
    });

    Olay bir Worker’dan gönderilir:

    const instance = await env.WORKFLOW.get(instanceId);
    await instance.sendEvent({ type: "review-decision", payload: { onaylandi: true } });

    Cron ile tetikleme

    {
      "workflows": [{
        "name": "gece-etl",
        "binding": "ETL",
        "class_name": "EtlWorkflow",
        "schedules": ["0 2 * * *"]
      }]
    }

    Resmî ifade: “you do not need top-level triggers.crons and a separate scheduled handler for Workflow-specific recurring runs.” Ücretli planda bu örnekler her tetiklenmede bir saate kadar eşzamanlılık kotası tüketmeden çalışabilir.

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

    Uygun olduğu işler

    • Sipariş, ödeme, abonelik gibi telafi gerektiren çok adımlı süreçler
    • İnsan onayı bekleyen akışlar
    • Günler süren kullanıcı yaşam döngüsü kampanyaları
    • Uzun süren, sayfalanmış ETL işleri
    • Yapay zekâ hatları — pahalı bir model çağrısı başarılıysa retry’da tekrar çalışmaz

    Uygun olmadığı işler

    • İstek yolunda milisaniye hassasiyeti. Her adım kalıcı bir kontrol noktasıdır, depolama G/Ç’si vardır.
    • Çok yüksek frekanslı, küçük, bağımsız işler. Adım başına ücret hızla birikir; Queues kullan.
    • Tek örnekte 10.000 adımı aşan döngüler. Parçala veya örneklere böl.
    • Büyük ara veriler. Adım sonucu 1 MiB, örnek durumu 1 GB (ücretlide) ile sınırlı.
    • Workers for Platforms. Desteklenmiyor.
    • Varlıklar arası kesin sıralama. Bu Durable Objects’in işi.
    • Canlı bağlantı / WebSocket. Yine Durable Objects.
    • 30 günden uzun sonuç saklama. Nihai sonucu kendin D1 veya R2’ye yaz.

    Workflows, Queues ve Durable Object alarmları

    WorkflowsQueuesDO alarmları
    İş birimiÇok adımlı programTek mesajTek nesnenin uyanması
    Adımlar arası stateÖrtük — motor saklarYokKendi DO deponda
    Günlerce bekleme365 güne kadar, kota tüketmezdelaySeconds en fazla 24 saatsetAlarm() ama nesne başına tek alarm
    RetryAdım başına, 10.000’e kadarMesaj başına, 100 + dead-letter2 sn’den üstel, 6 deneme
    Duvar saatiAdım başına sınırsızTüketici başına 15 dkİşleyici başına 15 dk
    İnsan onayıYerleşik (waitForEvent)YokElle
    TelafiYerleşik rollbackYokYok

    Somut örnekler

    1. Sipariş süreci — telafili

    import { WorkflowEntrypoint } from "cloudflare:workers";
    import { NonRetryableError } from "cloudflare:workflows";
    
    export class SiparisWorkflow extends WorkflowEntrypoint {
      async run(event, step) {
        const { siparisId, kullaniciId, tutarKurus, sku, adet } = event.payload;
    
        const cekim = await step.do(
          "kartı çek",
          { retries: { limit: 3, delay: "10 seconds", backoff: "exponential" }, timeout: "2 minutes" },
          async () => {
            // Idempotency: daha önce çekildi mi?
            const mevcut = await this.env.DB
              .prepare("SELECT cekim_id FROM cekimler WHERE siparis_id = ?")
              .bind(siparisId).first();
            if (mevcut) return { cekimId: mevcut.cekim_id };
    
            const res = await fetch("https://api.odeme.example/cekimler", {
              method: "POST",
              headers: { "Idempotency-Key": siparisId },
              body: JSON.stringify({ kullaniciId, tutarKurus }),
            });
            if (res.status === 402) throw new NonRetryableError("kart reddedildi");
            if (!res.ok) throw new Error(`ödeme API ${res.status}`);
    
            const { id } = await res.json();
            await this.env.DB.prepare("INSERT INTO cekimler (siparis_id, cekim_id) VALUES (?, ?)")
              .bind(siparisId, id).run();
            return { cekimId: id };
          },
          {
            rollback: async ({ output, error }) => {
              if (!output) return;
              await fetch(`https://api.odeme.example/cekimler/${output.cekimId}/iade`, {
                method: "POST",
                headers: { "Idempotency-Key": `iade-${siparisId}` },
                body: JSON.stringify({ sebep: error.message }),
              });
            },
          },
        );
    
        // Bu adım kalıcı olarak başarısız olursa yukarıdaki iade otomatik çalışır.
        await step.do("stoğu ayır", async () => {
          const stub = this.env.STOK.getByName(`sku:${sku}`);
          const ok = await stub.ayir(siparisId, adet);
          if (!ok) throw new NonRetryableError(`stok yok: ${sku}`);
        });
    
        // Ayrı adım: e-posta sağlayıcısı hata verirse kart tekrar çekilmemeli.
        await step.do("onay e-postası gönder", async () => {
          await fetch("https://api.eposta.example/gonder", {
            method: "POST",
            body: JSON.stringify({ to: kullaniciId, sablon: "siparis-onay", siparisId }),
          });
        });
    
        // Günler sonra. Beklerken hiçbir maliyeti yok.
        await step.sleep("yorum istemeden önce bekle", "3 days");
        await step.do("yorum iste", async () => {
          await fetch("https://api.eposta.example/gonder", {
            method: "POST",
            body: JSON.stringify({ to: kullaniciId, sablon: "yorum-iste", siparisId }),
          });
        });
    
        return { siparisId, cekimId: cekim.cekimId, durum: "tamamlandi" };
      }
    }

    2. İnsan onayı bekleyen yayın akışı

    export class YayinWorkflow extends WorkflowEntrypoint {
      async run(event, step) {
        const { dokumanAnahtari, isteyenEposta } = event.payload;
    
        const ozet = await step.do("dokümanı özetle", async () => {
          const nesne = await this.env.BUCKET.get(dokumanAnahtari);
          if (!nesne) throw new NonRetryableError(`nesne yok: ${dokumanAnahtari}`);
          const metin = (await nesne.text()).slice(0, 20_000);
          const cikti = await this.env.AI.run("@cf/meta/llama-3.1-8b-instruct", {
            messages: [{ role: "user", content: `3 madde halinde özetle:\n\n${metin}` }],
          });
          return { ozet: cikti.response };   // 1 MiB altında kalmalı
        });
    
        await step.do("gözden geçirenlere haber ver", async () => {
          await fetch("https://api.eposta.example/gonder", {
            method: "POST",
            body: JSON.stringify({
              to: "inceleme@sirket.com",
              konu: `Onay: ${dokumanAnahtari}`,
              govde: ozet.ozet,
              onayUrl: `https://api.sirket.com/onayla?instanceId=${event.instanceId}`,
            }),
          });
        });
    
        // Sıfır maliyetle bekler. Günlerce sürebilir.
        let karar;
        try {
          karar = await step.waitForEvent("kararı bekle", {
            type: "inceleme-karari",
            timeout: "7 days",
          });
        } catch {
          await step.do("zaman aşımını yükselt", async () => {
            await fetch("https://api.eposta.example/gonder", {
              method: "POST",
              body: JSON.stringify({ to: isteyenEposta, sablon: "inceleme-zaman-asimi" }),
            });
          });
          return { yayinlandi: false, sebep: "zaman aşımı" };
        }
    
        if (!karar.onaylandi) {
          return { yayinlandi: false, sebep: "reddedildi", kim: karar.inceleyen };
        }
    
        await step.do("yayınla", async () => {
          const nesne = await this.env.BUCKET.get(dokumanAnahtari);
          await this.env.BUCKET.put(`public/${dokumanAnahtari}`, nesne.body);
        });
        return { yayinlandi: true, kim: karar.inceleyen };
      }
    }

    3. Sayfalanmış ETL — adım sınırına dikkat ederek

    const SAYFA_BOYUTU = 500;
    const AZAMI_SAYFA = 2000;   // sınırlı: adım tavanının altında kalır
    
    export class EtlWorkflow extends WorkflowEntrypoint {
      async run(event, step) {
        const baslangic = event.payload?.baslangic
          ?? new Date((event.schedule?.scheduledTime ?? Date.now()) - 86_400_000).toISOString();
    
        let imlec = null, sayfa = 0, toplam = 0;
    
        while (sayfa < AZAMI_SAYFA) {
          // Adım adı sayaçtan türüyor — deterministik.
          const parca = await step.do(
            `sayfa ${sayfa} çek`,
            { retries: { limit: 8, delay: "15 seconds", backoff: "exponential" }, timeout: "10 minutes" },
            async () => {
              const url = new URL("https://api.kaynak.example/kayitlar");
              url.searchParams.set("baslangic", baslangic);
              if (imlec) url.searchParams.set("imlec", imlec);
    
              const res = await fetch(url);
              if (res.status === 429) throw new Error("rate limit");  // retry edilir
              if (!res.ok) throw new Error(`kaynak ${res.status}`);
              const govde = await res.json();
    
              // Adım yalnızca REFERANS döndürür, veriyi değil — 1 MiB sınırı böyle aşılmaz.
              const anahtar = `staging/${baslangic}/sayfa-${sayfa}.ndjson`;
              await this.env.GOL.put(anahtar, govde.kayitlar.map(k => JSON.stringify(k)).join("\n"));
              return { anahtar, adet: govde.kayitlar.length, sonrakiImlec: govde.sonrakiImlec };
            },
          );
    
          toplam += parca.adet;
          imlec = parca.sonrakiImlec;
          sayfa++;
          if (!imlec) break;
    
          // Uyumak adım sayılmaz ve bedava.
          if (sayfa % 20 === 0) await step.sleep(`sayfa ${sayfa} sonrası bekle`, "30 seconds");
        }
    
        return { sayfa, kayit: toplam };
      }
    }

    4. Toplu örnek oluşturma

    // createBatch: 100'erli gruplar, ve create()'in aksine idempotent
    for (let i = 0; i < kullaniciIdleri.length; i += 100) {
      const grup = kullaniciIdleri.slice(i, i + 100).map((id) => ({
        id: `ozet-${id}-${new Date().toISOString().slice(0, 10)}`,
        params: { kullaniciId: id },
      }));
      await env.OZET_WORKFLOW.createBatch(grup);
    }

    Demo 1: Çok adımlı süreç ve retry davranışı

    Adım 1 — Kurulum

    npm create cloudflare@latest workflows-starter -- --template "cloudflare/workflows-starter"
    cd workflows-starter
    npx wrangler types
    npx wrangler dev
    C3 çıktısı ve ardından wrangler dev'in bindings bölümünde MY_WORKFLOW satırı

    Adım 2 — Örnek başlat

    curl http://localhost:8787
    # { "instanceId": "..." }
    İki curl çıktısı yan yana: örnek oluşturma ve ardından ?instanceId= ile status sorgusu (running durumu)

    Adım 3 — Adımları izle

    npx wrangler workflows instances describe my-workflow latest
    Terminal — her adımın durumu, dönüş değeri, sleep'in ne zaman biteceği ve retry sayıları

    Adım 4 — Kasten hata üret

    Bir adıma geçici olarak throw new Error("test") ekle ve retry’ları izle.

    describe çıktısında aynı adımın birden çok attempt kaydı ve üstel artan bekleme süreleri
    Workers & Pages → Workflows → örnek listesi; errored, running ve complete durumundaki örnekler bir arada

    Adım 5 — Görselleştirici

    Bir örneğin adım adım akış diyagramı; hangi adımın ne kadar sürdüğü görünsün

    Demo 2: İnsan onayı bekleyen akış

    Adım 1 — waitForEvent ile bekleyen bir workflow yaz

    describe veya panel çıktısı — örneğin 'waiting' durumunda olduğu ve hangi event type'ını beklediği

    Adım 2 — Olayı gönder

    curl -X POST "https://<worker>/onayla?instanceId=<ID>" \
      -H 'content-type: application/json' \
      -d '{"onaylandi": true, "inceleyen": "samet"}'
    Olay gönderildikten sonraki describe çıktısı — waiting'den running'e geçiş ve sonraki adımların çalışması

    Adım 3 — Zaman aşımını dene

    Timeout süresi dolduğunda describe çıktısındaki hata ve catch bloğunun çalıştığını gösteren sonraki adım

    Adım 4 — Rollback’i tetikle

    Bir adım kalıcı hata verdiğinde describe çıktısında rollback handler'larının ters sırayla çalıştığı bölüm

    Ölçüm

    ÖlçütDeğer
    Uyurken tüketilen CPU
    Uyurken tüketilen eşzamanlılık kotası
    Retry sonrası tekrar çalışan adım sayısı
    Rollback tetiklenme sırası

    Fiyatlandırma

    Rakamlar 31 Ağustos 2026’da resmî dokümantasyondan doğrulanmıştır.

    Dört faturalama boyutu var:

    BirimÜcretsizÜcretli
    İstek (çağrı)Günde 100.000 (Workers ile ortak)Ayda 10 milyon dahil, sonrası milyon başına 0,30 USD
    CPU süresiÇağrı başına 10 msAyda 30 milyon CPU ms dahil, sonrası milyon başına 0,02 USD
    Depolama1 GBAyda 1 GB dahil, sonrası 0,20 USD / GB-ay
    AdımGünde 3.000Ayda 500.000 dahil, sonrası 100.000 adım başına 0,80 USD

    Önemli notlar:

    • Uyuyan veya API yanıtı bekleyen bir workflow CPU tüketmez.
    • Adım sayısına rollback handler’ları ve retry’lar dahil değildir.
    • Depolama, çalışan/hatalı/uyuyan/tamamlanmış tüm örnekleri kapsar.
    • Alt istekler ek istek ücreti doğurmaz.

    Limitler

    ÖzellikÜcretsizÜcretli
    Adım başına CPU10 ms30 sn (varsayılan), 5 dk’ya kadar
    Adım başına duvar saatiSınırsızSınırsız
    Adım sonucu (akış dışı)1 MiB1 MiB
    Örnek başına saklanan state100 MB1 GB
    step.sleep azami süre365 gün365 gün
    Workflow başına adım1.02410.000 (25.000’e kadar ayarlanabilir)
    Eşzamanlı çalışan örnek10050.000
    Örnek oluşturma hızısn’de 100hesapta sn’de 300, workflow’da 100
    Sonuç saklama3 gün30 gün
    Örnek başına alt istek5010.000 (10 milyona kadar)
    Adım başına retry10.00010.000

    Sınırları yükseltmek:

    {
      "limits": { "cpu_ms": 300000, "subrequests": 10000000 },
      "workflows": [{ "name": "etl", "binding": "ETL", "class_name": "EtlWorkflow",
                      "limits": { "steps": 25000 } }]
    }

    Lisanslama ve hukuki çerçeve

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

    Workflow state’i Cloudflare’in altyapısında saklanır ve varsayılan olarak 30 gün (ücretsizde 3 gün) tutulur. Adım dönüş değerleri bu state’in parçasıdır — yani adımlardan döndürdüğün her şey Cloudflare’de saklanır. Kişisel veri veya sır içeren değerleri adım çıktısı olarak döndürmemek, bunun yerine referans döndürüp veriyi kendi kontrolündeki bir yerde tutmak iyi bir alışkanlıktır. retention ayarıyla saklama süresini kısaltabilirsin.

    Sık yapılan hatalar

    Adım dışında state biriktirmek. Resmî örnek: imageList will be not persisted across engine’s lifetimes. Which means that after hibernation, imageList will be empty again, even though the following two steps have already ran.” State adımlardan döndürülmeli.

    Deterministik olmayan adım adları. Date.now(), Math.random() veya UUID içeren adım adları önbelleklemeyi tamamen bozar.

    Adımların dışında yan etki üretmek. Resmî ifade: “Operations outside of a step.do might be repeated more than once.” Veritabanına yazma, API çağırma, başka bir workflow başlatma — hepsi adım içinde olmalı.

    await unutmak. Resmî uyarı: “If you don’t call await step.do or await step.sleep, you create a dangling Promise.” Sonuç: erken loglama, yutulan hatalar, kaybolan state.

    Dev adımlar yazmak. Üç API çağrısını tek adıma koyarsan, üçüncüsü hata verdiğinde üçü birden yeniden çalışır.

    Idempotent olmayan adımlar. Kart çekme klasik örnek. Sağlayıcının idempotency anahtarını kullan ve yerel bir kayıt kontrolü ekle.

    Kalıcı hataları retry etmek. 402, 401, 422 gibi yanıtlar NonRetryableError olmalı, yoksa 5 deneme boşa gider.

    event: yerine type: kullanmamak. waitForEvent seçeneğinin adı type’dır. Cloudflare’in kendi ana sayfa örneği bu konuda hatalıdır.

    Kullanıcı kimliğini instance ID olarak kullanmak. Aynı kullanıcı için ikinci bir workflow başlatamazsın.

    Döngüde create() çağırmak. createBatch() kullan; ayrıca hesap başına saniyede 300 örnek oluşturma sınırı var, aşınca HTTP 429 alırsın.

    retention ayarlamamak. Yüksek hacimli workflow’larda tamamlanmış örnekler 30 gün boyunca depolama olarak faturalanır.

    Sıkça sorulan sorular

    Bir Workflow ne kadar süre çalışabilir?
    Pratikte sonsuza kadar. Resmî ifade: “A Workflow instance can run forever, as long as each step does not take more than the CPU time limit and the maximum number of steps per Workflow is not reached.” Adım başına duvar saati sınırı yok; tek bir step.sleep en fazla 365 gün olabilir. Asıl tavan adım sayısıdır: ücretli planda varsayılan 10.000, en fazla 25.000. step.sleep bu sayıya dahil değildir.
    Uyuyan bir Workflow bana para veya kapasite yakar mı?
    CPU yakmaz: “A Workflow that is waiting on a response to an API call, paused as a result of calling step.sleep, or otherwise idle, does not incur CPU time.” Eşzamanlılık kotası da yakmaz — yalnızca running durumundakiler sayılır, dolayısıyla milyonlarca örnek aynı anda uyuyabilir. Ama depolama ücreti işlemeye devam eder; depolama uyuyan ve tamamlanmış örnekleri de kapsar.
    Adımım neden iki kez çalıştı?
    İki olasılık var. Ya hata fırlattı ve retry edildi (varsayılan: 5 deneme, 10 saniyeden başlayan üstel geri çekilme), ya da adı deterministik değil. Adım adı önbellek anahtarıdır; step.do(`adım ${Date.now()}`) her çalışmada yeni anahtar üretir, dolayısıyla hiçbir şey önbelleğe alınmaz. Ayrıca adımların dışındaki kod motor yeniden başladığında tekrar çalışır.
    Aynı instance ID’sini tekrar kullanabilir miyim?
    create() ile hayır: “Throws an error if the provided ID is already used by an existing instance that has not yet passed its retention limit.” Sipariş veya işlem kimliği gibi doğal olarak benzersiz bir değer kullan, ya da ${kullaniciId}-${crypto.randomUUID().slice(0,6)} gibi bileşik bir kimlik üret. İstisna: createBatch() idempotenttir, çakışan kimliği atlar. Aynı kimliği yeniden çalıştırmak için instance.restart() var.
    terminate() ile NonRetryableError arasındaki fark nedir?
    NonRetryableError adımın içinden fırlatılır: o adımın retry’larını durdurur ve tüm örneği anında başarısız yapar. terminate() ise dışarıdan, binding üzerinden çağrılır. İkisi de telafi çalıştırabilir: terminate({ rollback: true }) kayıtlı rollback handler’larını çalıştırır, NonRetryableError sonrasında da rollback’ler örneği sonlandırmadan önce çalışır.
    Adım sonucum 1 MiB’dan büyük, ne yapmalıyım?
    Tercih sırasıyla üç yol var. (1) Veriyi R2 veya D1’e yaz, adımdan yalnızca anahtarı döndür — resmî öneri de bu. (2) ReadableStream<Uint8Array> döndür (yalnızca JavaScript; akış taze ve kilitsiz olmalı, BYOB desteklenmiyor, parçalar 16 MB altında). Ama bu da örnek başına 1 GB depolama sınırına sayılır. (3) Adımı böl.
    Workflows mu, Queues mu, Cron Triggers mı?
    Cron Triggers → 15 dakikada biten, state tutmayan periyodik iş. Queues → çok sayıda bağımsız, birbirinin aynı iş parçası; yük tepesini yayma, at-least-once teslim. Workflows → adımları birbirine bağımlı, kısmi ilerlemesi korunması gereken, 15 dakikadan uzun sürebilen veya insan onayı bekleyen süreç. Pratik kural: bir cron işi 15 dakikayı aşmaya başladıysa ya da veritabanında durum kolonu ve retry döngüsü yazmaya başladıysan, aradığın şey Workflows.
    Workflow içinde Hyperdrive veya veritabanı bağlantısı kullanabilir miyim?
    Evet, ama tek bir kuralla. Resmî ifade: “If you use Hyperdrive in a Workflow, create a new connection inside each step.do() and run your queries in that same step. Do not reuse a Hyperdrive-backed connection across steps.” Genel kural: bağlantı gibi serileştirilemeyen kaynaklar adımlar arasında taşınamaz.
    Workflows artık kendi cron’unu çalıştırabiliyor mu?
    Evet, ve bu Cron Triggers karşılaştırmasını değiştiriyor. Binding’e schedules ekleyerek üst düzey triggers.crons ve ayrı bir scheduled handler yazmadan periyodik örnek üretebilirsin. Ücretli planda ek bir avantaj var: cron ile üretilen örnekler her tetiklenmede bir saate kadar eşzamanlılık kotası tüketmeden çalışabilir. Sınır: hesap başına 100 cron ifadesi.
    Workers for Platforms üzerinde Workflows kullanabilir miyim?
    Hayır. Resmî ifade: “Workflows cannot be deployed to Workers for Platforms namespaces, as Workflows do not support Workers for Platforms.” Çok kiracılı bir platform kuruyorsan bu önemli bir kısıt.
    waitForEvent neden çalışmıyor?
    Muhtemelen yanlış anahtar kullanıyorsun. Cloudflare’in kendi ana sayfa örneği { event: 'approved' } yazıyor ama API referansı seçeneğin adının type olduğunu söylüyor. Doğrusu type, ve sendEvent içindeki type ile birebir eşleşmeli. Bu, resmî dokümandaki bilinen bir hatadır.
    Fatura sürprizi nereden gelir?
    Adım sayısından. Ücretli planda ayda 500.000 adım dahil, sonrası 100.000 adım başına 0,80 USD. Çok konuşkan bir workflow (her satır için bir adım) hızla pahalılaşır. İkinci kaynak depolama: retention ayarlamazsan tamamlanmış örnekler 30 gün boyunca GB-ay olarak faturalanır.

    İlgili servisler

    • WorkersJavaScript/TypeScript/Python kodunu Cloudflare’in 330+ şehirdeki sunucularında, sunucu yönetmeden çalıştırır.
    • Queuesİşleri kuyruğa alıp arka planda batch ve garantili biçimde işler.
    • Durable ObjectsHer nesnenin tek bir instance’ı olan, state tutan compute; sohbet odası, oyun oturumu, sayaç gibi işler için.
    • D1Workers’a bağlanan serverless SQLite veritabanı.
    • R2S3 uyumlu object storage — çıkış (egress) trafiği ücretsiz.

    Bu sayfadaki fiyat ve özellik bilgileri 31 Ağustos 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.