Durable Objects
Her nesnenin dünyada tek bir instance’ı olan, yanında kendi SQLite veritabanını taşıyan state’li compute.
- DurumGenel kullanımda
- Fiyatİstek + süre (GB-saniye) + SQL satır okuma/yazma + depolama
- Ücretsiz katmanvar
- Doğrulama
Durable Objects nedir?
Sunucusuz fonksiyonlar state tutmaz ve yatay olarak dağılır. İki eşzamanlı isteğin tek bir değer üzerinde anlaşması gerektiğinde — bir koltuk rezervasyonu, bir sayaç, bir sohbet odasının üye listesi, bir rate limit bütçesi — dışarıdan bir koordinasyon katmanı eklemek zorunda kalırsın: Redis ve kilitler, işlemsel bir veritabanı, bir kilit servisi.
Durable Objects bunu ortadan kaldırır. Platform, verilen bir kimlik için dünyada tek bir instance’ın çalıştığını garanti eder ve o instance’a kendi özel, yanı başında duran, güçlü tutarlı SQLite veritabanını verir.
Cloudflare’in kendi tanımı:
“Each Durable Object has a globally-unique name, which allows you to send requests to a specific object from anywhere in the world. […] Each Durable Object has some durable storage attached. Since this storage lives together with the object, it is strongly consistent yet fast to access.”
Nasıl çalışır?
Teklik garantisi ve eşzamanlılık
Bir Durable Object tek iş parçacıklıdır ve işbirlikçi çoklu görev kullanır — resmî benzetmeyle “tarayıcıda çalışan kod gibi”. Eşzamanlılık güvenliği input gate denen mekanizmayla sağlanır. Resmî ifade: “You do not have to worry about a concurrent request having modified the value in storage. ‘input gates’ will automatically protect against unwanted concurrency. Read-modify-write is safe.”
Yumuşak tavan: nesne başına saniyede 1.000 istek. Aşılınca overloaded hatası döner.
Adresleme
| Yöntem | Ne yapar |
|---|---|
getByName(ad) | Güncel önerilen yol. Addan kimlik üretip stub döndürür. |
idFromName(ad) | Addan deterministik kimlik üretir. |
newUniqueId() | Rastgele benzersiz kimlik; teklik kontrolünü atlar, daha hızlıdır. |
idFromString(hex) | Daha önce metne çevrilmiş kimliği geri yükler. |
get(id, { locationHint }) | Kimlikten stub üretir, konum ipucu verilebilir. |
Nesne tembel oluşturulur: kimlik üretmek nesneyi yaratmaz, ilk get çağrısı yaratır.
// Güncel biçim
{
"durable_objects": {
"bindings": [{ "name": "SOHBET", "class_name": "SohbetOdasi" }]
},
"exports": {
"SohbetOdasi": { "type": "durable-object", "storage": "sqlite" }
}
}
// Eski biçim — hâlâ destekleniyor, yeni projelerde kullanma
{ "migrations": [{ "tag": "v1", "new_sqlite_classes": ["SohbetOdasi"] }] }
Yaşam döngüsü değişikliklerinin üç katı kuralı var:
- “Lifecycle changes cannot be applied via
wrangler versions upload” - “Gradual deployments don’t support lifecycle changes”
- “Rollbacks cannot cross a lifecycle change”
Depolama
SQLite backend’inde iki API bir arada bulunur:
// SQL API — senkron, event loop'u bırakmaz, dolayısıyla atomik
const satirlar = ctx.storage.sql
.exec("SELECT ad, puan FROM oyuncular ORDER BY puan DESC LIMIT ?", 10)
.toArray();
// KV API — senkron veya asenkron
ctx.storage.kv.put("sayac", 42);
await ctx.storage.put("sayac", 42);
İki tuzak:
Cursor’ı await üzerinden taşıma. Resmî uyarı: “A cursor resumed after an await may
observe rows inserted, updated, or deleted after the cursor was created.” Cursor’ı await
öncesinde .toArray() ile tüket.
BEGIN TRANSACTION çalıştırma. sql.exec() işlem ifadelerini kabul etmez; transactionSync()
veya transaction() kullan.
Alarmlar
Nesne başına tek alarm vardır; setAlarm() mevcut olanı ezer. Yeniden deneme davranışı:
“Alarms have guaranteed at-least-once execution and are retried automatically when the alarm()
handler throws. Retries are performed using exponential backoff starting at a 2 second delay from
the first failure with up to 6 retries allowed.”
Alarm işleyicisinin duvar saati sınırı 15 dakika. Her setAlarm() bir satır yazma olarak
faturalanır.
WebSocket hibernation
Bu, Durable Objects’te para kazandıran tek en önemli özelliktir.
ws.accept() çağırırsan nesne WebSocket açık kaldığı sürece ücretlendirilir. Resmî ifade:
“Calling accept() on a WebSocket in an Object will incur duration charges for the entire time
the WebSocket is connected.”
ctx.acceptWebSocket(ws) çağırırsan nesne mesajlar arasında hibernate olabilir ve yalnızca mesaj
işlenirken ücretlendirilir.
| Nesne başına sınır | |
|---|---|
| Hibernation ile WebSocket bağlantısı | 32.768 |
| WebSocket başına etiket | 10 (her biri en fazla 256 karakter) |
serializeAttachment boyutu | 16.384 bayt |
| Otomatik yanıt metni | 2.048 karakter |
| Alınan mesaj boyutu | 32 MiB |
İstemci heartbeat’i için setWebSocketAutoResponse kullan — resmî ifade: “the auto-response will
be returned without waking WebSockets in hibernation and incurring billable duration charges.”
Mesaj gruplama önerisi resmî dokümanda net: “Batch every 50-100ms or every 50-100 messages, whichever comes first.”
Konum ipuçları ve yargı alanları
Yargı alanları — kesin garanti: eu, us, fedramp.
Konum ipuçları — garanti değil: wnam, enam, sam, weur, eeur, apac, apac-ne,
apac-se, oc, afr, me. Resmî uyarı: “Hints are a best effort and not a guarantee.”
Ne zaman kullanılır, ne zaman kullanılmaz
Uygun olduğu işler
- Sohbet odaları, işbirlikçi doküman düzenleme, çok oyunculu oyun oturumları
- Koltuk/stok rezervasyonu — tek iş parçacıklı olduğu için gerçek bir compare-and-set
- Kullanıcı veya kiracı başına rate limiting
- Her varlığın kendi küçük veri kümesine sahip olduğu çok kiracılı yapılar
- WebSocket sunucusu gerektiren her şey
Uygun olmadığı işler
- Tüm verin üzerinde toplu sorgu. Her nesnenin deposu kendine özeldir; nesneler arası
SELECTyoktur. Fan-out/fan-in senin sorunun. - Tek bir global sayaç veya singleton. Bir nesne = bir iş parçacığı = saniyede ~1.000 istek. Parçala.
- Okuma ağırlıklı, global dağıtık, bayatlığa toleranslı veri. KV bunun için var; nesnenin tek bir ev konumu vardır, uzaktaki okuyucular gidiş-dönüş maliyeti öder.
- Büyük ikili veriler. Nesne başına 10 GB, satır/BLOB başına 2 MB. R2 kullan.
- Hibernate edilemeyen uzun ömürlü bağlantılar. Giden bir WebSocket veya
setInterval, nesneyi 7/24 ücretlendirilen durumda tutar. - ORM’li klasik ilişkisel veritabanı. Hyperdrive + PostgreSQL veya D1 kullan.
Somut örnekler
1. Sayaç — oku-değiştir-yaz güvenli
import { DurableObject } from "cloudflare:workers";
export class Sayac extends DurableObject {
async deger() {
return (await this.ctx.storage.get("deger")) ?? 0;
}
async artir(miktar = 1) {
let deger = (await this.ctx.storage.get("deger")) ?? 0;
deger += miktar;
// Input gate sayesinde bu oku-değiştir-yaz atomik. Kilit gerekmiyor.
await this.ctx.storage.put("deger", deger);
return deger;
}
}
export default {
async fetch(request, env) {
const ad = new URL(request.url).searchParams.get("ad");
if (!ad) return new Response("?ad= gerekli", { status: 400 });
// get(ad) DEĞİL — get() bir DurableObjectId bekler, string değil.
const stub = env.SAYACLAR.getByName(ad);
return new Response(String(await stub.artir()));
},
};
2. Sohbet odası — hibernation + SQL geçmişi
import { DurableObject } from "cloudflare:workers";
export class SohbetOdasi extends DurableObject {
constructor(ctx, env) {
super(ctx, env);
// Şema kurulumu blockConcurrencyWhile'ın meşru kullanımıdır.
ctx.blockConcurrencyWhile(async () => {
ctx.storage.sql.exec(`
CREATE TABLE IF NOT EXISTS mesajlar (
id INTEGER PRIMARY KEY AUTOINCREMENT,
kullanici TEXT NOT NULL,
govde TEXT NOT NULL,
ts INTEGER NOT NULL
)`);
});
// Heartbeat'e hibernate'ten uyanmadan cevap ver — ücretlendirilmez.
ctx.setWebSocketAutoResponse(new WebSocketRequestResponsePair("ping", "pong"));
}
async fetch(request) {
const kullanici = new URL(request.url).searchParams.get("kullanici") ?? "anonim";
const [istemci, sunucu] = Object.values(new WebSocketPair());
// ws.accept() DEĞİL — accept() bağlantı boyunca ücret yazdırır.
this.ctx.acceptWebSocket(sunucu, [`kullanici:${kullanici}`]);
sunucu.serializeAttachment({ kullanici }); // hibernation'ı atlatır, max 16 KB
return new Response(null, { status: 101, webSocket: istemci });
}
async webSocketMessage(ws, mesaj) {
if (typeof mesaj !== "string") return;
const { kullanici } = ws.deserializeAttachment();
const ts = Date.now();
this.ctx.storage.sql.exec(
"INSERT INTO mesajlar (kullanici, govde, ts) VALUES (?, ?, ?)",
kullanici, mesaj, ts,
);
const paket = JSON.stringify({ kullanici, govde: mesaj, ts });
for (const peer of this.ctx.getWebSockets()) peer.send(paket);
}
async gecmis(limit = 50) {
return this.ctx.storage.sql
.exec("SELECT kullanici, govde, ts FROM mesajlar ORDER BY id DESC LIMIT ?", limit)
.toArray(); // await'ten önce senkron tüket
}
}
3. Rate limiter — kendi kendini temizleyen
const PENCERE_MS = 60_000;
const LIMIT = 100;
export class RateLimiter extends DurableObject {
async kontrol() {
const simdi = Date.now();
this.ctx.storage.sql.exec("DELETE FROM vurus WHERE ts < ?", simdi - PENCERE_MS);
const { n } = this.ctx.storage.sql
.exec("SELECT COUNT(*) AS n FROM vurus").one();
if (n >= LIMIT) return { izin: false, kalan: 0 };
this.ctx.storage.sql.exec("INSERT INTO vurus (ts) VALUES (?)", simdi);
// Kimse dönmezse alarm tabloyu siler ve depolama ücreti ödemeyi bırakırız.
if ((await this.ctx.storage.getAlarm()) === null) {
await this.ctx.storage.setAlarm(simdi + PENCERE_MS * 2);
}
return { izin: true, kalan: LIMIT - n - 1 };
}
async alarm() {
this.ctx.storage.sql.exec("DELETE FROM vurus WHERE ts < ?", Date.now() - PENCERE_MS);
const { n } = this.ctx.storage.sql.exec("SELECT COUNT(*) AS n FROM vurus").one();
if (n > 0) await this.ctx.storage.setAlarm(Date.now() + PENCERE_MS);
else await this.ctx.storage.deleteAll(); // tüm faturalanabilir depolamayı boşaltır
}
}
// Worker: her IP kendi nesnesine düşer — global darboğaz yok
// await env.RATE_LIMITER.getByName(`ip:${ip}`).kontrol()
4. Koltuk rezervasyonu — gerçek compare-and-set
export class KoltukHaritasi extends DurableObject {
async tut(koltuk, tutan, ttlMs = 300_000) {
const simdi = Date.now();
const satir = this.ctx.storage.sql
.exec("SELECT tutan, gecerli_son FROM koltuklar WHERE koltuk = ?", koltuk)
.toArray()[0];
if (satir?.tutan && satir.tutan !== tutan && satir.gecerli_son > simdi) {
return { ok: false, sebep: "başkası tutuyor" };
}
this.ctx.storage.sql.exec(
"INSERT OR REPLACE INTO koltuklar (koltuk, tutan, gecerli_son) VALUES (?,?,?)",
koltuk, tutan, simdi + ttlMs,
);
return { ok: true, bitis: simdi + ttlMs };
}
}
Bu kodda ne advisory lock var, ne SELECT ... FOR UPDATE. Nesne tek iş parçacıklı ve SQL senkron
olduğu için bu zaten atomik.
Demo 1: Hibernation’lı sohbet odası
Adım 1 — Proje kurulumu
npm create cloudflare@latest -- sohbet
cd sohbet
Adım 2 — Yapılandırma
{
"name": "sohbet",
"main": "src/index.ts",
"compatibility_date": "2026-08-31",
"observability": { "enabled": true },
"durable_objects": {
"bindings": [{ "name": "SOHBET", "class_name": "SohbetOdasi" }]
},
"exports": {
"SohbetOdasi": { "type": "durable-object", "storage": "sqlite" }
}
}
npx wrangler types # wrangler.jsonc her değiştiğinde tekrar çalıştır
npx wrangler dev
Adım 3 — İki tarayıcıdan bağlan
Adım 4 — Yayına al ve gözlemle
npx wrangler deploy
npx wrangler tail
Demo 2: Hibernation’ın maliyet farkını ölçme
Bu demo sayfanın en önemli iddiasını doğrular: hibernation gerçekten ~7 kat fark yaratıyor mu?
Adım 1 — Hibernation’sız sürümü çalıştır
ctx.acceptWebSocket(sunucu) yerine geçici olarak:
sunucu.accept();
sunucu.addEventListener("message", (e) => { /* ... */ });
Adım 2 — Hibernation’lı sürüme dön
Adım 3 — Otomatik yanıtı doğrula
ctx.setWebSocketAutoResponse(new WebSocketRequestResponsePair("ping", "pong"));
Ölçüm: öncesi ve sonrası
Demo tamamlandığında gerçek değerlerle doldurulacak.
| Ölçüt | ws.accept() | ctx.acceptWebSocket() |
|---|---|---|
| Süre tüketimi (GB-s / saat) | — | — |
| Ping mesajı başına maliyet | — | — |
| Nesne hibernate oldu mu | hayır | — |
| Cloudflare referans örneği (aylık) | 142,95 USD | 20,65 USD |
Fiyatlandırma
Rakamlar 31 Ağustos 2026’da resmî dokümandan doğrulanmıştır.
Hesaplama
| Ücretsiz | Ücretli | |
|---|---|---|
| İstek | Günde 100.000 | Ayda 1 milyon dahil, sonrası milyon başına 0,15 USD |
| Süre | Günde 13.000 GB-s | Ayda 400.000 GB-s dahil, sonrası milyon GB-s başına 12,50 USD |
Kritik ayrıntılar:
- Süre, nesnenin 128 MB belleği için ücretlendirilir — gerçek kullanımdan bağımsız.
- Gelen WebSocket mesajlarına faturalamada 20:1 oranı uygulanır: 100 mesaj 5 istek sayılır.
- Giden WebSocket mesajları ve gelen protokol ping’leri ücretsizdir.
- Bir RPC oturumu tek istek olarak faturalanır; aynı stub üzerindeki sonraki çağrılar ayrı istek değildir.
setWebSocketAutoResponseile yanıtlanan mesajlar duvar saati tüketmez, ücretlendirilmez.
SQLite depolama
| Ücretsiz | Ücretli | |
|---|---|---|
| Satır okuma | 5 milyon/gün | Ayda ilk 25 milyar dahil, sonrası milyon satır başına 0,001 USD |
| Satır yazma | 100.000/gün | Ayda ilk 50 milyon dahil, sonrası milyon satır başına 1,00 USD |
| Depolanan veri | 5 GB | 5 GB-ay dahil, sonrası 0,20 USD / GB-ay |
Cloudflare’in kendi maliyet örnekleri
| Senaryo | Aylık |
|---|---|
| 1 nesne, 1,5M istek, ayda 1.000.000 sn aktif | 5,15 USD |
| 100 nesne × 50 WebSocket, dakikada 1 mesaj, günde 8 saat, hibernation yok | 142,95 USD |
| 100 nesne, nesne başına 1 WebSocket, saniyede 1 mesaj, ay boyu aktif | 419,30 USD |
| 100 nesne × 100 hibernate edilebilir WebSocket, dakikada 1 mesaj | 20,65 USD |
İkinci ile dördüncü satırı karşılaştır: aynı büyüklükteki iş yükü, 7 kat maliyet farkı.
Lisanslama ve hukuki çerçeve
Durable Objects tescilli bir hizmettir; kullanımı Cloudflare Hizmet Şartları ile düzenlenir.
Veri konumu açısından önemli: Bir Durable Object’in verisi tek bir fiziksel konumda durur ve
o konum ilk erişimin geldiği yere göre belirlenir. Yargı alanı (jurisdiction) kesin bir
kısıttır — eu seçilirse veri Avrupa Birliği içinde kalır. Konum ipucu (locationHint) ise
garanti değildir.
Türkiye için tanımlı bir Durable Objects yargı alanı yoktur. Verinin Türkiye’de kalması gerekiyorsa Durable Objects uygun bir seçenek değildir.
Sık yapılan hatalar
ws.accept() kullanmak. Durable Objects’teki en pahalı hata. Bağlantı açık kaldığı sürece
ücret yazar. Doğrusu ctx.acceptWebSocket(ws).
Tick için setInterval kullanmak. Hibernation’ı kalıcı olarak engeller ve 7/24 GB-s
faturalar. Doğrusu setAlarm() — alarm hibernate olmuş nesneyi uyandırabilir.
Sınıf alanlarında gerçek state tutmak. Resmî ifade: “In-memory state is reset when the Durable Object hibernates.” Sınıf alanlarını yalnızca önbellek olarak gör; kaynak her zaman depo olmalı.
Constructor’da ağır iş yapmak. Hibernation altında constructor her uyanışta çalışır.
Cursor’ı await üzerinden taşımak. await öncesinde .toArray() ile tüket.
migrations ile exports’u karıştırmak. Aynı Worker’da ikisi birden kullanılamaz.
Kapanış kancası beklemek. Yoktur. Resmî öneri: “write your position to storage as you go rather than waiting to persist it at the end.”
Biten nesneleri temizlememek. Veri silinene kadar depolama ücreti işler. TTL alarmıyla
deleteAll() çağır.
Tüm trafiği tek bir global nesneye yönlendirmek. Saniyede ~1.000 istek tavanına çarparsın. Varlık bazında parçala.
Sıkça sorulan sorular
- Bir kimlik için gerçekten dünyada tek bir instance mı var?
- Evet. Resmî ifade: “Global Uniqueness guarantees that there will be a single instance of a Durable Object class with a given ID running at once, across the world.” Bu garanti o kadar katıdır ki, nesne kapanırken devam eden bir istek depoya erişmeye çalışırsa istek anında durdurulup hata döner — tekliği korumak için.
- getByName() mi newUniqueId() mi kullanmalıyım?
- Kimlik senin alan modelinden geliyorsa (
oda:lobi,kullanici:123,kiraci:acme)getByName()kullan — dünyanın her yerinden aynı ada aynı nesne düşer. Sadece yeni bir nesne lazımsa ve kimliği kendin saklayacaksannewUniqueId()kullan. Önemli fark: bir ada ilk kez erişirken sistem dünyanın öbür ucunda aynı adın aynı anda oluşturulmadığını doğrulamak zorunda. Resmî ifade: “Due to the inherent limit of the speed of light, this round-the-world check can take up to a few hundred milliseconds.”newUniqueId()bu kontrolü atlar. - Yazma işlemlerimi blockConcurrencyWhile ile sarmalamam gerekir mi?
- Neredeyse hiç gerekmez. Resmî ifade: “SQLite storage operations are synchronous and do not yield the event loop, so they execute atomically without it. For asynchronous KV storage operations, input gates already prevent other requests from interleaving.” Yani oku-değiştir-yaz zaten güvenli.
blockConcurrencyWhile’ı constructor’daki şema kurulumu için ve dış birfetchsırasında state değişmesini kaldıramadığın durumlar için sakla. Dikkat: callback 30 saniyede bitmezse nesne sıfırlanır. - Nesnem neden hibernate olmuyor ve bu bana neye mal oluyor?
- Hibernation için beş koşulun hepsi sağlanmalı:
setTimeout/setIntervalyok, devam edenfetch()yok, standart WebSocket API’si kullanılmıyor, işlenmekte olan istek yok, açık giden TCP/WebSocket bağlantısı yok. Biri bile ihlal edilirse nesne bellekte kalır ve saniye başına ücretlendirilmeye devam eder. Hibernation 10 saniye hareketsizlikten sonra devreye girer; hibernate olamayan bir nesne 70–140 saniye sonra tamamen tahliye edilir. - WebSocket hibernation gerçekten fark yaratıyor mu?
- Cloudflare’in kendi fiyat örnekleri cevabı veriyor. Aynı iş yükü — 100 nesne, nesne başına WebSocket’ler, dakikada bir mesaj — hibernation olmadan ayda 142,95 USD, hibernation ile ayda 20,65 USD. Yaklaşık 7 kat fark. Durable Objects’te maliyet optimizasyonu esas olarak bu tek karardır.
- ctx.waitUntil() ile arka plan işi yapabilir miyim?
- Hayır. Resmî ifade: “Unlike in Workers,
waitUntilhas no effect in Durable Objects. It does not extend the lifetime of a Durable Object or affect when a request or RPC completes.” Gerçekten ertelenmiş iş için alarm kullan — alarm hibernate olmuş bir nesneyi uyandırabilir. - Nesne başına tek alarm varsa birden çok zamanlanmış iş nasıl yönetilir?
- Zamanlama tablosunu SQL’de tut ve alarmı her zaman en yakın vadeye kur.
alarm()içinde vadesi gelen her şeyi işle, sonra alarmı bir sonrakiMIN(vade)değerine yeniden kur. Resmî doküman da tam bu deseni öneriyor. Not: hersetAlarm()çağrısı bir satır yazma olarak faturalanır. - KV depolama backend’inden SQLite’a geçebilir miyim?
- Yerinde geçiş yok. Resmî ifade: “Storage type is immutable once provisioned—changing backends requires deletion and re-provisioning with data loss.” Ayrıca yeni namespace’ler yalnızca
sqliteolabilir;legacy-kvsadece hâlihazırda var olanlar için. Ücretsiz planda KV backend hiç kullanılamaz. - Durable Objects mı, D1 mi, KV mi?
- Basit kural: KV → tek bir paylaşılan veri kümesi, çok okunur, az yazılır, bayatlık sorun değil. D1 → tek bir paylaşılan ilişkisel veri kümesi, JOIN ve satırlar arası sorgu gerekiyor. Durable Objects → çok sayıda küçük, bağımsız veri kümesi, her varlık için bir tane (kullanıcı başına, oda başına, kiracı başına), her biri güçlü tutarlılık ve/veya bir koordinasyon noktası gerektiriyor.
- Bir sınıfı silersem veya adını değiştirirsem verilerime ne olur?
- Silme geri dönüşsüzdür: “Deletion removes all stored data permanently—copy needed data elsewhere first.” Ad değiştirme kesintisiz yapılabilir ama üç aşamalı deploy gerektirir (yeni adı takma ad olarak ekle → yeniden adlandır → takma adı kaldır). Ayrıca yaşam döngüsü değişiklikleri
wrangler versions uploadile veya kademeli deploy ile uygulanamaz, ve rollback bir yaşam döngüsü değişikliğinin ötesine geçemez. - Tek bir nesneye ne kadar yük bindirebilirim?
- Resmî yumuşak sınır: “An individual Object has a soft limit of 1,000 requests per second.” Aşılınca
overloadedhatası alırsın. Tek bir global nesne mimari bir darboğazdır — varlık bazında parçala (kullanıcı, oda, kiracı). Ayrıca istekler arasında 30 saniyeden fazla CPU harcarsan nesnenin tahliye edilip sıfırlanma ihtimali artar. - Boş bir nesne için de ödeme yapıyor muyum?
- Evet, az da olsa. Resmî ifade: “An empty SQLite database consumes approximately 12 KB of storage.” Ayrıca her yazma iç tablolarda metadata bırakır ve bu metadata
deleteAll()çağrılana kadar durur. İşi biten nesneleri bir TTL alarmıyla temizlemek gerçek para tasarrufu sağlar.
İ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ı.
- Workers KVOkuma ağırlıklı, global olarak replike edilen key-value store.
- 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.
- ContainersDocker image’ını Cloudflare ağında çalıştırır; Workers’a sığmayan diller, gerçek filesystem ve ağır bağımlılıklar için.
- Queuesİşleri kuyruğa alıp arka planda batch ve garantili biçimde işler.
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.