İçeriğe atla
Cloudflare Wiki

    gez · aç · Esc kapat

    Workers KV

    Okuma ağırlıklı, global olarak replike edilen key-value store.

    • DurumGenel kullanımda
    • FiyatOkuma, yazma, silme ve list işlemi sayısı + depolama
    • Ücretsiz katmanvar
    • Doğrulama

    Workers KV nedir?

    Bir yapılandırma değerini, bir oturum kaydını veya bir feature flag’i dünyanın her yerinden 10 milisaniyenin altında okumak istiyorsun. Veritabanı turu bunun için fazla pahalı.

    Workers KV bu ihtiyacı karşılar. Resmî tanım:

    “KV is a global, low-latency, key-value data store. It stores data in a small number of centralized data centers, then caches that data in Cloudflare’s data centers after access.”

    Bedeli net: eventual consistency.

    Nasıl çalışır?

    Replike edilmiş veritabanı değil, merkezi depo + CDN cache

    Bu ayrım KV’yi anlamanın anahtarıdır:

    “When you write to KV, your data is written to central data stores. Your data is not sent automatically to every location’s cache.”

    “Initial reads from a location do not have a cached value. Data must be read from the nearest regional tier, followed by a central tier, degrading finally to the central stores for a truly cold global read. While the first access is slow globally, subsequent requests are faster.”

    Sıcak anahtarlarda tipik gecikme 500 µs – 10 ms. Soğuk okuma belirgin biçimde yavaştır.

    Tutarlılık — bu sayfanın en önemli bölümü

    Türk kaynaklarında en çok yanlış aktarılan konu budur.

    Aynı konumda yapılan yazma genellikle hemen görünür — ama resmî uyarı devam ediyor: “this is not guaranteed and therefore it is not advised to rely on this behaviour.”

    Anahtar başına saniyede bir yazma

    Eşzamanlı yazmalarda kilit yoktur: “If concurrent writes are made to the same key, the last write will take precedence.” Yani kayıp güncelleme sessizce olur.

    cacheTtl

    Değer
    Minimum30 saniye
    Varsayılan60 saniye
    MaksimumNumber.MAX_SAFE_INTEGER

    Yükseltmek okuma maliyetini ve gecikmeyi düşürür, bayatlığı uzatır. expiration her zaman cacheTtl’i ezer — süresi dolan anahtar cache süresi ne olursa olsun silinir.

    Metadata

    Anahtar başına en fazla 1.024 bayt JSON. getWithMetadata() ve list() ile döner.

    Resmî öneri: “Consider storing your values in metadata if your values fit in the metadata-size limit. Storing values in metadata is more efficient than a list() followed by a get() per key.”

    list() ve sayfalama

    Varsayılan ve maksimum limit 1.000 anahtar. Anahtarlar UTF-8 baytlarına göre leksikografik sırada döner.

    İki kritik kural:

    list_complete is a boolean, which will be false if there are more keys to fetch, even if the keys array is empty.”

    “When de-paginating a large result set while also providing a prefix argument, the prefix argument must be provided in all subsequent calls.”

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

    Cloudflare’in kendi yönlendirmesi:

    “Workers KV is an eventually-consistent edge key-value store. That makes it ideal for read-heavy, highly cacheable workloads such as: Serving static assets / Storing application configuration / Storing user preferences / Implementing allow-lists/deny-lists / Caching”

    “If you have a write-heavy Redis-type workload where you are updating the same key tens or hundreds of times per second, KV will not be an ideal fit.”

    Uygun olmadığı işler

    • Sayaç, stok, rezervasyon, rate limit. Oku-değiştir-yaz güvenli değil, üstelik saniyede bir yazma sınırı var. → Durable Objects
    • Anında tutarlılık gereken her şey. → Durable Objects
    • İlişkisel sorgu, JOIN, ad-hoc SQL.D1
    • 25 MiB üstü değerler, medya, veri kümeleri.R2
    • Mevcut PostgreSQL/MySQL.Hyperdrive
    • Katı veri yerleşimi. Cache yargı bölgesinin dışına çıkabilir.

    Somut örnekler

    1. Feature flag — uzun cacheTtl

    export default {
      async fetch(request, env) {
        // Nadiren değişir → uzun cacheTtl, az soğuk okuma, düşük maliyet
        const bayraklar = await env.YAPILANDIRMA.get("bayraklar:web", {
          type: "json",
          cacheTtl: 3600,
        });
        return Response.json(bayraklar ?? { yeniOdeme: false });
      },
    };

    2. Oturum — TTL ve metadata ile

    // Giriş
    await env.OTURUMLAR.put(`oturum:${sid}`, JSON.stringify({ kullaniciId, roller }), {
      expirationTtl: 60 * 60 * 24 * 7,      // 7 gün; minimum 60 saniye
      metadata: { kullaniciId, olusturuldu: Date.now() },
    });
    
    // Her istekte — metadata ikinci bir okuma gerektirmez
    const { value, metadata } = await env.OTURUMLAR.getWithMetadata(
      `oturum:${sid}`, { type: "json" });
    
    if (value === null) return new Response("Yetkisiz", { status: 401 });
    
    // Çıkış
    await env.OTURUMLAR.delete(`oturum:${sid}`);

    3. Toplu okuma — en fazla 100 anahtar

    const idler = ["kullanici:1", "kullanici:2", "kullanici:3"];   // en fazla 100
    
    // Tek subrequest sayılır, ama N okuma olarak faturalanır
    const kullanicilar = await env.KULLANICILAR.get(idler, { type: "json", cacheTtl: 300 });
    
    for (const [anahtar, deger] of kullanicilar) {
      if (deger === null) console.log(`${anahtar} bulunamadı`);
    }

    4. Doğru sayfalama — değer metadata’da

    async function hepsiniListele(env, onek) {
      const cikti = [];
      let imlec;
    
      do {
        // prefix HER sayfada tekrar verilmeli
        const sayfa = await env.NS.list({ prefix: onek, cursor: imlec, limit: 1000 });
    
        for (const k of sayfa.keys) {
          cikti.push({ ad: k.name, deger: k.metadata?.deger });   // get() yok
        }
    
        // keys.length'e DEĞİL, list_complete'e bak
        imlec = sayfa.list_complete ? undefined : sayfa.cursor;
      } while (imlec);
    
      return cikti;
    }
    
    // Yazarken: değer metadata'ya konur
    await env.NS.put(anahtar, "", { metadata: { deger } });

    5. Yapılmaması gereken — sayaç

    // ❌ YANLIŞ: kayıp güncelleme + saniyede 1 yazma sınırında 429
    const n = Number(await env.KV.get("goruntuleme")) + 1;
    await env.KV.put("goruntuleme", String(n));
    
    // ✅ DOĞRU: Durable Object (kesin serileştirilebilirlik)
    const sayac = env.SAYACLAR.getByName("goruntuleme");
    await sayac.artir();

    6. Güçlü tutarlılık deseni

    Cloudflare’in belgelediği hibrit yaklaşım:

    // Yazmalar Durable Object üzerinden serileştirilir
    const yazici = env.KV_YAZICI.getByName(`anahtar:${anahtar}`);
    await yazici.yaz(anahtar, deger);   // DO içinde KV'ye yazar, sıraya sokar
    
    // Okumalar doğrudan KV'den — hızlı ve ucuz
    const deger = await env.KV.get(anahtar, { cacheTtl: 60 });

    Demo 1: Eventual consistency’yi ölçme

    Bu demo, sayfanın ana iddiasını kanıtlar: 60 saniye bir garanti değildir.

    Adım 1 — Yazma ve okuma uçları kur

    wrangler kv namespace create çıktısı ve wrangler.jsonc'a eklenen binding bloğu

    Adım 2 — Aynı konumdan yaz-oku

    curl -X POST https://<worker>/yaz -d '{"anahtar":"test","deger":"v1"}'
    curl https://<worker>/oku?anahtar=test
    İki curl çıktısı — yazma ve hemen ardından okuma; değerin göründüğü

    Adım 3 — Farklı coğrafyalardan oku

    Değeri güncelle, sonra farklı konumlardan aynı anahtarı oku.

    Birden çok konumdan yapılan okuma sonuçları — bazılarının eski değeri döndürdüğü; her yanıtta cdn-cgi/trace colo bilgisi
    Zaman damgalı log — güncellemeden sonra her konumun yeni değeri kaç saniyede gördüğü

    Adım 4 — Olumsuz cache’i doğrula

    Var olmayan bir anahtarı oku, sonra yaz, sonra tekrar oku.

    Üç işlem — önce null dönen okuma, sonra yazma, sonra hâlâ null dönen okuma

    Adım 5 — cacheTtl’in etkisi

    Aynı test yüksek cacheTtl ile — eski değerin çok daha uzun süre döndüğü

    Demo 2: Yazma sınırı ve maliyet

    Adım 1 — Saniyede birden fazla yazma dene

    for i in $(seq 1 10); do
      curl -s -X POST https://<worker>/yaz -d "{\"anahtar\":\"ayni\",\"deger\":\"$i\"}" &
    done
    wait
    wrangler tail çıktısı — KV PUT failed: 429 Too Many Requests hataları

    Adım 2 — Kayıp güncellemeyi göster

    10 paralel yazma sonrası okunan değer — arada kaç yazmanın kaybolduğu

    Adım 3 — list() maliyetini ölç

    Panel — KV metrik ekranında okuma, yazma ve list sayaçları ayrı ayrı

    Adım 4 — Metadata ile get() sayısını düşür

    Aynı listelemeyi önce get() ile, sonra metadata ile yap.

    İki ölçüm — 1.000 anahtar için toplam işlem sayısındaki fark

    Adım 5 — Durable Object ile çöz

    Aynı 10 paralel yazma testi DO üzerinden — hata yok, tüm güncellemeler korunmuş

    Ölçüm

    ÖlçütDeğer
    Aynı konumda yayılma süresi
    En uzak konumda yayılma süresi
    Olumsuz cache süresi
    10 paralel yazmada 429 sayısı
    10 paralel yazmada kaybolan güncelleme
    1.000 anahtar: get() vs metadata işlem sayısı

    Fiyatlandırma

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

    ÜcretsizÜcretli
    Okunan anahtarGünde 100.000Ayda 10 milyon, sonrası 0,50 USD / milyon
    Yazılan anahtarGünde 1.000Ayda 1 milyon, sonrası 5,00 USD / milyon
    Silinen anahtarGünde 1.000Ayda 1 milyon, sonrası 5,00 USD / milyon
    List isteğiGünde 1.000Ayda 1 milyon, sonrası 5,00 USD / milyon
    Depolama1 GB1 GB, sonrası 0,50 USD / GB-ay

    Egress ücreti yoktur.

    Diğer fatura ayrıntıları:

    • Toplu okuma anahtar başına faturalanır. Tek subrequest sayılır ama N okuma olarak ücretlenir.
    • Panel ve Wrangler işlemleri de faturalanır — anahtar listelemek dahil.
    • Olmayan anahtar okumak da faturalanır. “These operations still traverse KV’s infrastructure.”
    • REST API ile 5.000 anahtar yazmak, Worker’dan 5.000 PUT çağırmakla aynı maliyettedir.

    Limitler

    ÖzellikÜcretsizÜcretli
    OkumaGünde 100.000Sınırsız (metered)
    Farklı anahtarlara yazmaGünde 1.000Sınırsız (metered)
    Aynı anahtara yazmasaniyede 1saniyede 1
    Worker çağrısı başına işlem1.0001.000
    Hesap başına namespace1.0001.000
    Depolama1 GBSınırsız (metered)
    Namespace başına anahtarSınırsızSınırsız
    Anahtar boyutu512 bayt512 bayt
    Metadata boyutu1.024 bayt1.024 bayt
    Değer boyutu25 MiB25 MiB
    Minimum cacheTtl30 saniye30 saniye

    Tabloda olmayan ama geçerli sınırlar: toplu okuma 100 anahtar (yanıt 25 MB’ı aşarsa 413), toplu yazma/silme 10.000 çift ve toplam 100 MB, list() sayfası 1.000 anahtar, expirationTtl minimum 60 saniye.

    Anahtar boş olamaz, tam olarak . veya .. olamaz.

    Lisanslama ve hukuki çerçeve

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

    Veri yerleşimi — KV’nin zayıf noktası. Yargı bölgeleri (eu, fedramp, us) mevcut ama:

    • Private beta durumundalar
    • Yalnızca namespace oluşturulurken verilebiliyorlar
    • En önemlisi: jurisdiction kalıcı depolamayı bağlar ama cache o sınırın dışına çıkabilir

    Bu, D1 ile arasındaki belirleyici farktır — D1’de yargı bölgesi read replica’ları da kısıtlar. Katı veri yerleşimi yükümlülüğün varsa KV uygun değildir.

    Oturum verisi ve KVKK. KV oturum saklamak için resmî olarak önerilir, ama oturum verisi genellikle kişisel veri içerir ve:

    • Silme anında yayılmaz — 60 saniye veya daha uzun süre başka konumlarda geçerli kalabilir
    • expirationTtl kullanmak, unutulan kayıtların birikmesini engeller
    • Metadata’ya yazdığın her şey list() sonuçlarında da döner

    Sık yapılan hatalar

    Tek anahtar üzerinde oku-değiştir-yaz. Hem kayıp güncelleme hem saniyede 1 yazma sınırı. Sayaç, stok ve rate limit için Durable Objects kullan.

    60 saniyeyi tavan sanmak. Doküman “60 seconds or more” diyor; üst sınır yayımlanmamış.

    cacheTtl’i yükseltip hızlı geçersizleştirme beklemek. cacheTtl: 3600 bir saate kadar bayatlık demektir.

    Olumsuz cache’i unutmak. Oluşturmadan önce yapılan null okuma da cache’lenir; “oluştur, hemen oku” akışları kırılır.

    Farklı bir konumdan yazma-sonrası-okuma beklemek. wrangler dev’de çalışır, üretimde aralıklı olarak başarısız olur. Klasik KV hatası.

    Oturum iptali için KV’ye güvenmek. Çıkış ve engelleme 60 saniyeye kadar gecikir.

    if (sayfa.keys.length === 0) break; ile sayfalama. Silinmiş anahtarların arkasındaki kayıtları atlar. list_complete kullan.

    Sonraki list() sayfalarında prefix’i düşürmek.

    Cache doldurmayı sıcak yolda await etmek. ctx.waitUntil() kullan.

    Toplu yazmanın binding’de var olduğunu sanmak. Yok — yalnızca Wrangler veya REST.

    list() ve panel işlemlerinin ücretsiz olduğunu sanmak. Pahalı yazma tarifesinden faturalanır.

    Sıcak bir değeri çok sayıda soğuk anahtara bölmek. Doküman tersini öneriyor: okuma maliyeti ve gecikme için anahtarları birleştirmek (key coalescing) — ama güncelleme için kilit gerektirir.

    Sıkça sorulan sorular

    Bir yazma ne kadar sürede dünya geneline yayılır?
    Resmî ifade: “In other global network locations changes may take up to 60 seconds or more to be visible as their cached versions of the data time-out.” Dikkat: bu bir replikasyon SLA'sı değil, cache süresinin dolmasıdır. Üst sınır yayımlanmamıştır ve cacheTtl'i yükseltirsen bu süre uzar.
    “KV 60 saniyede senkronize olur” diye okudum, doğru mu?
    Hayır — ve bu yanlış bilginin kaynağı belli. Cloudflare'in 2019 tarihli GA blog yazısı “It can achieve global consistency in less than 60 seconds” diyor. Güncel dokümantasyon ise tam tersini söylüyor: “60 seconds or more. Yedi yıllık bir pazarlama yazısı ile güncel teknik doküman çelişiyor; dokümanı esas al. Türkçe kaynakların çoğunda dolaşan “60 saniye garantili” ifadesi yanlıştır.
    Aynı anahtara saniyede kaç kez yazabilirim?
    Bir kez. Resmî ifade: “Workers KV has a maximum of 1 write to the same key per second. Writes made to the same key within 1 second will cause rate limiting (429) errors to be thrown.” Hata: KV PUT failed: 429 Too Many Requests. Bu sınır ücretli planda da aynıdır — para ödeyerek aşamazsın.
    İki Worker aynı anahtara aynı anda yazarsa?
    Biri sessizce kaybolur. Resmî ifade: “If concurrent writes are made to the same key, the last write will take precedence.” Kilit veya karşılaştır-ve-değiştir mekanizması yoktur. Sayaç, stok, rezervasyon gibi işler için KV yanlış araçtır — Durable Objects kullan.
    Olmayan bir anahtarı okumak da faturalanıyor mu?
    Evet. Resmî ifade: “All operations incur charges, including fetches for non-existent keys that return a null (Workers API) or HTTP 404 (REST API). These operations still traverse KV's infrastructure.” Ayrıca olumsuz sonuçlar da cache'lenir — bir anahtarın yokluğu da 60 saniye boyunca hatırlanır.
    list() ucuz mu?
    Hayır — yazma tarifesinden faturalanır: milyon başına 5,00 USD, ücretsiz planda günde yalnızca 1.000. Okuma tarifesinin (0,50 USD/milyon, günde 100.000) on katı. İlginç bir ayrıntı: KV limit tablosunda list hiç geçmiyor, yalnızca fiyat sayfasında var.
    Anahtar başına get() yapmadan değerleri nasıl listelerim?
    Değeri metadata'ya koy. Resmî öneri: “Consider storing your values in metadata if your values fit in the metadata-size limit. Storing values in metadata is more efficient than a list() followed by a get() per key.” Metadata 1.024 bayta kadar ve list() sonucunda birlikte döner. 100.000 anahtarlık bir taramada bu, 100.000 okuma ile 100 list isteği arasındaki farktır.
    Sayfalamayı nasıl doğru yaparım?
    list_complete alanına bak, keys.length'e değil. Resmî uyarı: “Checking for an empty array in keys is not sufficient to determine whether there are more keys to fetch.” Sebep: yeni silinmiş veya süresi dolmuş anahtarlar taranır ama sonuca girmez — yani boş bir sayfa dönebilir ama arkasında hâlâ anahtar olabilir. Ayrıca prefix verdiysen her sayfada tekrar vermelisin.
    Worker'dan toplu yazma yapabilir miyim?
    Hayır. Resmî ifade: “Bulk writes are not supported using the KV binding.” Toplu okuma var (en fazla 100 anahtar, tek subrequest sayılır ama N okuma olarak faturalanır). Toplu yazma ve silme yalnızca Wrangler veya REST API ile, en fazla 10.000 çift ve toplam 100 MB.
    cacheTtl yükseltmek iyi bir fikir mi?
    Duruma göre. Yükseltmek okuma maliyetini ve gecikmeyi düşürür ama bayatlığı uzatır. Resmî uyarı: cacheTtl is not recommended if your data is updated often and you need to see updates shortly after they are written.” Minimum 30 saniye, varsayılan 60. Nadiren değişen yapılandırma için 3600 mantıklı; oturum verisi için değil.
    Oturum verisi için uygun mu?
    Cloudflare açıkça öneriyor: “We recommend using Workers KV for storing session data, credentials (API keys), and/or configuration data.” Cloudflare Access'in kendisi de kullanıyor. Ama bir uyarı: oturum iptali anında yayılmaz. Çıkış yapan veya engellenen bir kullanıcının oturumu başka bir konumda 60 saniye daha geçerli görünebilir. Kısa ömürlü token'larla birlikte kullan.
    Daha güçlü tutarlılık lazımsa ne yapmalıyım?
    Resmî olarak belgelenmiş bir desen var: “send all of your writes for a given KV key through a corresponding instance of a Durable Object, and then read that value from KV in other Workers.” Yazmaları Durable Object serileştirir, okumalar KV'nin hızından yararlanır. Alternatif olarak tamamen Durable Objects'e geçmek de mümkün.
    Verimi AB'de tutabilir miyim?
    Kısmen, ve D1'den daha zayıf. KV'de yargı bölgeleri var ama private beta ve yalnızca namespace oluşturulurken verilebiliyor. Daha önemlisi: jurisdiction kalıcı depolamayı bağlar ama cache o sınırın dışına çıkabilir“KV data can be cached outside the jurisdiction location.” D1'de ise replica'lar da yargı bölgesine hapsedilir. Katı veri yerleşimi gerekiyorsa KV uygun değildir.

    İlgili servisler

    • WorkersJavaScript/TypeScript/Python kodunu Cloudflare’in 330+ şehirdeki sunucularında, sunucu yönetmeden çalıştırır.
    • D1Workers’a bağlanan serverless SQLite veritabanı.
    • 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.
    • Cache ReserveStatik içeriği R2 üzerinde kalıcı olarak cache’ler; origin’e giden isteği azaltır.

    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.