Vectorize
Embedding vektörlerini küresel olarak dağıtık saklar ve benzerlik araması yapar; boşta dururken para yakmaz.
- DurumGenel kullanımda
- FiyatSorgulanan ve saklanan vektör boyutu başına
- Ücretsiz katmanvar
- Doğrulama
Vectorize nedir?
Vectorize, Cloudflare’in vector database’idir. Resmî tanım:
“Vectorize is a globally distributed vector database that enables you to build full-stack, AI-powered applications with Cloudflare Workers. Vectorize makes querying embeddings — representations of values or objects like text, images, audio that are designed to be consumed by machine learning models and semantic search algorithms — faster, easier and more affordable.”
Çözdüğü problem şu: embedding’lerin var ve bunlar üzerinde yaklaşık en yakın komşu (approximate nearest neighbour) araması yapman gerekiyor, ama bunun için bir veritabanı işletmek istemiyorsun.
Kritik bir nokta var ve mimarini bu belirliyor: Vectorize senin içeriğini saklamaz.
“A vector database is designed to store vector embeddings, which are representations of data, but not the original data itself.”
Yani vektörü ve küçük bir metadata’yı tutar, gerisini sen bağlarsın:
“The vectors returned can reference images stored in Cloudflare R2, documents in KV, and/or user profiles stored in D1 — enabling you to go from vector search result to concrete object all within the Workers platform, and without standing up additional infrastructure.”
26 Eylül 2024’te genel kullanıma açıldı (Birthday Week 2024). Öncesi: 27 Eylül 2023 açık beta, 14 Ağustos 2024 v2 açık beta ve v1’in deprecate edilmesi, 16 Eylül 2024 ücretsiz plana açılış.
Nasıl çalışır?
Index oluşturma
“Indexes are the ‘atom’ of Vectorize.”
Üç girdi gerekir: kebab-case bir ad, sabit bir boyut sayısı ve sabit bir mesafe metriği.
npx wrangler vectorize create urun-arama --dimensions=768 --metric=cosine
Wrangler 3.71.0 veya üstü gerekiyor (Vectorize V2 için).
Mesafe metrikleri
| Metrik | Resmî açıklama |
|---|---|
cosine | “Distance is measured between −1 (most dissimilar) to 1 (identical). 0 denotes an orthogonal vector.” |
euclidean | “Euclidean (L2) distance. 0 denotes identical vectors. The larger the positive number, the further the vectors are apart.” |
dot-product | “Negative dot product. Larger negative values or smaller positive values denote more similar vectors. A score of −1000 is more similar than −500, and a score of 15 more similar than 50.” |
dot-product metriğinin işaret mantığı ters çalışır; skor eşiği koyarken buna dikkat et.
Boyut sayısı
“Smaller output dimensions can be faster to search across, which can be useful for user-facing applications. Larger output dimensions can provide more accurate search, especially over larger datasets and/or datasets with substantially similar inputs.”
Resmî örnek boyutlar: Workers AI @cf/baai/bge-base-en-v1.5 → 768, OpenAI ada-002 → 1536,
Cohere embed-multilingual-v2.0 → 768, Google multimodalembedding → 1408.
Üst sınır 1536 boyut, 32 bit hassasiyet. Bu, modern 2048/4096 boyutlu bazı modelleri doğrudan kullanamayacağın anlamına gelir — kısaltman (Matryoshka) gerekir.
Insert ve upsert farkı
“If the same vector id is inserted twice in a Vectorize index, the index would reflect the vector that was added first.”
“If the same vector id is upserted twice in a Vectorize index, the index would reflect the vector that was added last.”
“Upserting does not merge or combine the values or metadata of an existing vector with the upserted vector: the upserted vector replaces the existing vector in full.”
İkisi de asenkrontur ve bir mutationId döndürür. Kabul edilen formatlar: number[],
Float32Array, Float64Array — ama “vector dimensions provided as Float64 will be converted to
Float32 before being stored.”
Yazma verimi — en çok gözden kaçan konu
Vectorize yazmaları önce bir write-ahead log’a alır, sonra asenkron bir iş R2’deki index dosyalarını okuyup güncellenmiş index’i yazar. Ve o işin bir toplu işleme sınırı vardır:
“It sets the maximum size of a batch to 200,000 total vectors or to 1,000 individual updates, whichever limit it hits first.”
Bunun pratik sonucu Cloudflare’in kendi örneğinde çarpıcı biçimde anlatılıyor:
“For example, let’s say we have 250,000 vectors we would like to insert… We decide to insert them one at a time, calling the insert API 250,000 times. Vectorize will only process 1000 vectors in each job, and will need to work through 250 total jobs. This could take at least an hour to do. The better approach is to batch our updates. For example, we can split our 250,000 vectors into 100 files, where each file has 2,500 vectors… Vectorize would update the index in only 2 or 3 jobs. All 250,000 vectors will visible in queries within minutes.”
Aynı veri, aynı sistem: bir saat mi, birkaç dakika mı — tek fark toplu yazmak.
Sorgulama
const eslesmeler = await env.VECTORIZE.query(sorguVektoru, {
topK: 5,
returnValues: true,
returnMetadata: 'all',
});
topK varsayılanı 5, üst sınırı 100 — ama returnValues: true veya
returnMetadata: 'all' kullanırsan 50’ye düşer.
returnMetadata üç modda çalışıyor ve aradaki fark önemli:
| Mod | Davranış |
|---|---|
none (varsayılan) | Metadata dönmez |
indexed | “Fetched metadata only for the indexed metadata fields. There is no latency overhead with this option, but long text fields may be truncated.” |
all | “Queries may run slower with this option, and topK is limited to 50.” |
Bir de az bilinen bir hassasiyet kaldıracı var:
“High-precision scoring is enabled by setting
returnValues: trueon your query. This setting tells Vectorize to use the original vector values for your matches, allowing the computation of exact match scores and increasing the accuracy of the results. Because it processes more data, though, high-precision scoring will increase the latency of queries.”
Varsayılan yaklaşık skorlama ise “a nice trade-off between accuracy and latency.”
Metadata filtreleme
“
filteris applied first, and thetopKresults are taken from the filtered set.”
Filtreleyeceğin her alan için vektörleri eklemeden önce bir metadata index’i oluşturman
gerekir. Index başına en fazla 10 tane; tipler string, number, boolean.
npx wrangler vectorize create-metadata-index urun-arama --property-name=kategori --type=string
npx wrangler vectorize list-metadata-index urun-arama
Operatörler: $eq $ne $in $nin $lt $lte $gt $gte.
Kısıtlar, resmî ifadelerle:
- Filtre JSON’u “must be less than 2048 bytes”
- Anahtarlar
" | .içeremez,$ile başlayamaz, 512 karakteri geçemez - “Upper-bound range queries (i.e.
$ltand$lte) can be combined with lower-bound range queries (i.e.$gtand$gte) within the same filter. Other combinations are not allowed.” - “Range queries involving a large number of vectors (~10M and above) may experience reduced accuracy.”
- String index’lerde yalnızca ilk 64 byte indexlenir
- Number index’lerde hassasiyet float64
Faydalı bir hile: “ile başlayan” araması için aralık kullanılır —
{ "kategori": { "$gte": "net", "$lt": "neu" } }.
Namespace
“A namespace filter is applied before metadata filter(s).”
“When a namespace is specified in a query operation, only vectors within that namespace are used for the search. Namespace filtering is applied before vector search, increasing the precision of the matched results.”
“A vector can only be part of a single namespace.”
Multi-tenant bir SaaS’ta kiracı ayrımı için doğru araç budur — metadata filtresi değil.
Workers AI ile bağlantı
const sorgu = await env.AI.run('@cf/baai/bge-base-en-v1.5', { text: [kullaniciSorgusu] });
const eslesmeler = await env.VECTORIZE.query(sorgu.data[0], { topK: 5 });
Dikkat: “Passing queryVector or queryVector.data will cause query() to return an error.”
Doğrusu sorgu.data[0].
Ne zaman kullanılır, ne zaman kullanılmaz
Kullanılır
- Boşta duran bir vector DB’ye para ödemek istemiyorsan. Ayrıştırıcı özellik bu: “You are not billed for CPU, memory, ‘active index hours’, or the number of indexes you create.” Pinecone serverless index’i veya sürekli açık bir Qdrant node’u sıfır sorguda bile para yakar; Vectorize yakmaz.
- Sorgular Worker’ının yanında çalışacaksa. Küresel dağıtık okuma, ayrı bir bölgeye gitmeden.
- Deneme yapıyorsan. 50.000 index açabilirsin ve boş index bedava. Boyut A/B testi maliyetsiz.
- RAG mimarisini kendin kuruyorsan ve chunking, retrieval, rerank adımlarını kontrol etmek istiyorsan.
Kullanılmaz
Tek bir korpusta 20 milyondan fazla vektörün varsa. Sert sınır index başına 20.000.000. Pinecone, Qdrant ve Milvus bunun ötesinde shard’lar; Vectorize shard’lamaz.
1536’dan fazla boyut gerekiyorsa. Sert sınır. text-embedding-3-large’ı tam 3072 boyutta
kullanamazsın.
Boyutu veya metriği sonradan değiştirmen gerekebilecekse. pgvector’de ALTER var, burada yok.
Filtreleyeceğin alanları baştan bilmiyorsan. Metadata index’i vektörlerden önce oluşturulmalı. Qdrant ve pgvector mevcut veri üzerinde istediğin zaman payload index’i ekletir; Vectorize her şeyi yeniden yüklemeni ister.
Yazma sonrası okuma tutarlılığı gerekiyorsa. Yazmalar asenkron, “birkaç saniye”. “Kullanıcı belge yükledi, hemen arattı” senaryosunda arayüzde bekleme durumu göstermek zorundasın.
10’dan fazla filtrelenebilir alan veya karmaşık boolean filtre gerekiyorsa. 10 metadata index,
2048 byte filtre JSON’u, keyfi $and/$or iç içeliği yok, aralık operatörlerinde tek yön çifti.
Hybrid arama (BM25, seyrek vektör, füzyon) gerekiyorsa. Vectorize yalnızca yoğun (dense) vektör araması yapar. Anahtar kelime index’i yok. Cloudflare’in bu ihtiyaca cevabı Vectorize değil, onun üstüne BM25 ekleyen AI Search.
HNSW/IVF parametreleri, quantization seçimi veya kendi kendine barındırma istiyorsan. Hiçbir
index algoritması ayarı dışarı açılmamış — tek kaldıraç returnValues: true.
Kaynak içeriği veritabanından geri almak istiyorsan. Vectorize vektör ve en fazla 10 KiB metadata tutar; içeriği R2/D1/KV’den kendin çekersin.
Somut örnekler
Aşağıdaki örneklerin hepsi şu wrangler.jsonc ile çalışır:
{
"vectorize": [{ "binding": "VECTORIZE", "index_name": "urun-arama" }],
"ai": { "binding": "AI" },
"r2_buckets": [{ "binding": "BELGELER", "bucket_name": "belgeler" }]
}
Kategori ve fiyat filtreli ürün araması
npx wrangler vectorize create urun-arama --dimensions=768 --metric=cosine
npx wrangler vectorize create-metadata-index urun-arama --property-name=kategori --type=string
npx wrangler vectorize create-metadata-index urun-arama --property-name=fiyat_tl --type=number
const q = await env.AI.run('@cf/baai/bge-m3', { text: [kullaniciSorgusu] });
const eslesmeler = await env.VECTORIZE.query(q.data[0], {
topK: 20,
filter: {
kategori: { $in: ['ayakkabi', 'bot'] },
fiyat_tl: { $gte: 500, $lte: 2500 },
},
returnMetadata: 'indexed',
});
returnMetadata: 'indexed' seçimi bilinçli: gecikme maliyeti yok ve topK 100’e kadar
çıkabiliyor.
Multi-tenant SaaS — namespace ile izolasyon
// Yazma
await env.VECTORIZE.upsert(
vektorler.map((v) => ({ ...v, namespace: `kiraci-${kiraciId}` })),
);
// Okuma
const eslesmeler = await env.VECTORIZE.query(sorguVektoru, {
namespace: `kiraci-${kiraciId}`,
topK: 10,
});
Namespace vektör aramasından önce uygulandığı için hem daha hızlı hem de bir kiracının diğerinin verisini görmesi yapısal olarak imkânsız.
Yinelenen içerik tespiti
const benzerler = await env.VECTORIZE.queryById(yeniBelgeId, { topK: 5 });
const yinelenen = benzerler.matches.some(
(m) => m.id !== yeniBelgeId && m.score > 0.97, // cosine
);
queryById embedding’i yeniden hesaplatmadan index’teki mevcut vektörle arama yapar — hem daha
ucuz hem daha hızlı.
“Buna benzer” önerisi, R2’ye bağlanarak
const m = await env.VECTORIZE.query(kaynakVektor, { topK: 6, returnMetadata: 'indexed' });
const nesneler = await Promise.all(
m.matches.slice(1).map((x) => env.BELGELER.get(String(x.metadata.r2_anahtar))),
);
İlk sonucu atlıyoruz çünkü o kaynak öğenin kendisi.
Zaman pencereli RAG — kovalanmış timestamp
npx wrangler vectorize create-metadata-index bilgi --property-name=ts_5dk --type=number
await env.VECTORIZE.upsert([{
id, values,
metadata: {
ts_5dk: Math.floor(Date.now() / 300000) * 300000, // indexlenir
ts_tam: Date.now(), // indexlenmez
},
}]);
// Son 24 saat
const m = await env.VECTORIZE.query(qv, {
topK: 10,
filter: { ts_5dk: { $gte: Date.now() - 86400000, $lt: Date.now() } },
});
Kardinalite uyarısının pratik karşılığı budur: filtrelenen alan kaba, gösterilen alan hassas.
Veri hattından toplu yükleme (Python)
url = "https://api.cloudflare.com/client/v4/accounts/{}/vectorize/v2/indexes/{}/insert".format(ACC, IDX)
with open('embeddings.ndjson', 'rb') as f:
resp = requests.post(url,
headers={"Authorization": f"Bearer {TOKEN}"},
files=dict(vectors=f))
Resmî uyarı: “Please use a maximum of 5000 vectors per embeddings.ndjson file to prevent
the global rate limit for the Cloudflare API.”
Demo 1: Metadata filtreleme ve sessiz başarısızlık
Bu demonun üç amacı var: filtre-önce semantiğini görmek, metadata index’ini geç oluşturmanın hiç hata vermeden sıfır sonuç döndürdüğünü kanıtlamak, ve yazma görünürlüğü gecikmesini ölçmek.
Adım 1 — Index’i ve metadata index’lerini oluştur
Boyutu küçük tutuyoruz (32) — demo ucuz ve hızlı olsun.
npx wrangler vectorize create demo-meta --dimensions=32 --metric=cosine
npx wrangler vectorize create-metadata-index demo-meta --property-name=platform --type=string
npx wrangler vectorize create-metadata-index demo-meta --property-name=yil --type=number
Adım 2 — Metadata index’lerinin oluştuğunu doğrula
Oluşturma asenkron; birkaç saniye bekle.
npx wrangler vectorize list-metadata-index demo-meta
Adım 3 — Vektörleri yükle ve görünürlük gecikmesini ölç
npx wrangler vectorize upsert demo-meta --file=tohum.ndjson
# Görünürlüğü izle — bu adımın kendisi ölçüm
while :; do npx wrangler vectorize info demo-meta; sleep 2; done
vectorCount 0’dan 5’e çıkana kadar geçen duvar saati süresini not et — bu senin yazma
görünürlüğü gecikmen.
Adım 4 — Filtreli ve filtresiz sorguyu karşılaştır
Worker’da üç rota aç:
export interface Env { VECTORIZE: Vectorize }
const QV = [54.8, 5.5, 3.1 /* … 32 float … */];
export default {
async fetch(req, env): Promise<Response> {
const p = new URL(req.url).pathname;
const t0 = Date.now();
let r;
if (p === '/filtresiz') {
r = await env.VECTORIZE.query(QV, { topK: 3, returnMetadata: 'all' });
} else if (p === '/filtreli') {
r = await env.VECTORIZE.query(QV, {
topK: 3, filter: { platform: 'netflix' }, returnMetadata: 'all',
});
} else if (p === '/aralik') {
r = await env.VECTORIZE.query(QV, {
topK: 3, filter: { yil: { $gte: 2022, $lt: 2025 } }, returnMetadata: 'indexed',
});
} else {
return new Response('404', { status: 404 });
}
return Response.json({ ms: Date.now() - t0, ...r });
},
} satisfies ExportedHandler<Env>;
npx wrangler deploy
curl -s https://<worker>/filtresiz | jq '{count, ids:[.matches[].id], ms}'
curl -s https://<worker>/filtreli | jq '{count, ids:[.matches[].id], ms}'
Görülmesi gereken: topK: 3 istedin ama filtreli sorgu 2 sonuç döndü. Filtre önce çalıştığı
için, normalde ilk üçe giremeyecek düşük skorlu bir kayıt listeye girdi. Bu tek ekran görüntüsü
“filter is applied first” cümlesini bir paragraftan daha iyi anlatıyor.
Adım 5 — Aralık ve “ile başlar” filtrelerini dene
curl -s https://<worker>/aralik | jq '{count, ids:[.matches[].id]}'
Adım 6 — Sessiz başarısızlığı üret
Şimdi asıl demo. Aynı veriyi yanlış sırayla yükleyelim:
npx wrangler vectorize create demo-bozuk --dimensions=32 --metric=cosine
npx wrangler vectorize upsert demo-bozuk --file=tohum.ndjson # ÖNCE vektörler
npx wrangler vectorize create-metadata-index demo-bozuk \
--property-name=platform --type=string # SONRA index
Sonra platform: 'netflix' filtresiyle sorgula.
Hiçbir hata yok, sadece count: 0. Sebep: “Vectors upserted before a metadata index was
created won’t have their metadata contained in that index.”
Adım 7 — Düzelt ve yeniden ölç
Aynı id’lerle aynı dosyayı tekrar upsert et, info ile mutation’ın işlenmesini bekle, sorguyu
tekrarla.
Adım 8 — Panoda ve faturada gör
Bu demoda ölçülenler: yazma görünürlüğü gecikmesi (saniye) · filtreli ve filtresiz sorgu
gecikmesi · returnMetadata modlarının gecikme farkı · topK tavanının 50’ye düştüğü nokta ·
faturalanan boyut sayısı.
Demo 2: Boyut sayısının gerçek maliyeti
Bu demo bir karar tablosu üretiyor: 384, 768 ve 1024 boyut arasında seçim yaparken tam olarak neyi neyle takas ediyorsun.
Üç Workers AI embedding modeli ve doğrulanmış fiyatları:
| Model | Boyut | Fiyat |
|---|---|---|
@cf/baai/bge-small-en-v1.5 | 384 | $0.020 / milyon giriş token’ı |
@cf/baai/bge-base-en-v1.5 | 768 | $0.067 / milyon giriş token’ı |
@cf/baai/bge-large-en-v1.5 | 1024 | $0.204 / milyon giriş token’ı |
Adım 1 — Üç index aç
npx wrangler vectorize create boyut-384 --dimensions=384 --metric=cosine
npx wrangler vectorize create boyut-768 --dimensions=768 --metric=cosine
npx wrangler vectorize create boyut-1024 --dimensions=1024 --metric=cosine
Adım 2 — Aynı korpusu üç index’e yükle
const MODEL = {
V384: '@cf/baai/bge-small-en-v1.5',
V768: '@cf/baai/bge-base-en-v1.5',
V1024: '@cf/baai/bge-large-en-v1.5',
} as const;
// 100'lük gruplar hâlinde — tek tek değil
for (let i = 0; i < belgeler.length; i += 100) {
const grup = belgeler.slice(i, i + 100);
const e = await env.AI.run(MODEL[idx], { text: grup });
await env[idx].upsert(
e.data.map((v, j) => ({ id: String(i + j), values: v })),
);
}
Adım 3 — Gold set ile isabet oranını ölç
30–60 gerçek kullanıcı sorusu ve her biri için doğru cevabın bulunduğu belge kimliği hazırla. Destek kayıtlarından veya site arama loglarından çıkar — uydurma soru kullanma.
for I in V384 V768 V1024; do
while IFS=$'\t' read -r soru dogru; do
curl -s "https://<worker>/?idx=$I&q=$(printf %s "$soru" | jq -sRr @uri)" \
| jq -c --arg g "$dogru" --arg i "$I" \
'{idx:$i, ilk1:(.ids[0]==$g), ilk5:(.ids[0:5]|index($g)!=null), embed_ms, query_ms}'
done < goldset.tsv
done | tee sonuclar.jsonl
Adım 4 — Maliyeti resmî formülle hesapla
Resmî formül:
((sorgulanan vektör + saklanan vektör) × boyut × ($0.01 / 1.000.000))
+ (saklanan vektör × boyut × ($0.05 / 100.000.000))
Senaryo: 100.000 saklanan vektör, ayda 500.000 sorgu.
| Boyut | Vectorize $/ay | 768’e göre |
|---|---|---|
| 384 | $2.32 | 0,50× |
| 768 | $4.65 | 1,00× |
| 1024 | $6.20 | 1,33× |
Maliyet boyutta tam doğrusal. Ücretsiz kota da ters orantılı ölçekleniyor: ücretli plandaki 10 milyon saklanan boyut, 384’te 26.041, 768’de 13.020, 1024’te 9.765 vektöre denk geliyor.
Embedding tarafı (100.000 belge × ~250 token = 25M token yükleme; ayda 500.000 sorgu × 20 token = 10M token):
| Boyut / Model | Yükleme | Aylık sorgu | Workers AI 1. ay |
|---|---|---|---|
| 384 / bge-small | $0.50 | $0.20 | $0.70 |
| 768 / bge-base | $1.68 | $0.67 | $2.35 |
| 1024 / bge-large | $5.10 | $2.04 | $7.14 |
Birinci ay toplamı: 384 → ~$3.02, 768 → ~$7.00, 1024 → ~$13.34. 1024 boyutlu kurulum, 384 boyutlunun 4,4 katı.
Adım 5 — Karar tablosunu doldur
| Ölçüt | 384 | 768 | 1024 |
|---|---|---|---|
| Recall@1 | ölç | ölç | ölç |
| Recall@5 | ölç | ölç | ölç |
embed_ms p50 | ölç | ölç | ölç |
query_ms p50 / p95 | ölç | ölç | ölç |
| Vectorize $/ay | $2.32 | $4.65 | $6.20 |
| Workers AI $/ay | $0.20 | $0.67 | $2.04 |
| Ücretsiz depolamaya sığan vektör | 26.041 | 13.020 | 9.765 |
Yayımlanabilir sonuç: 1024 boyuta ancak Recall@5 kazancı yaklaşık 4,4 kat maliyeti haklı çıkarıyorsa geç. Cloudflare’in kendi ifadesi de bunu söylüyor: “Larger output dimensions can provide more accurate search, especially over larger datasets and/or datasets with substantially similar inputs.” — yani kazanç korpusun büyüklüğüne ve içeriğin birbirine benzerliğine bağlı. Küçük ve çeşitli bir korpusta 384 fazlasıyla yeterli olabilir.
Bu demoda ölçülenler: boyut başına Recall@1 ve Recall@5 · embedding ve sorgu gecikmesi · Vectorize aylık maliyeti · Workers AI aylık maliyeti · ücretsiz kotaya sığan vektör sayısı.
Fiyatlandırma
Model
| Workers Free | Workers Paid | |
|---|---|---|
| Sorgulanan vektör boyutu | Ayda 30 milyon | İlk 50 milyon dahil, sonrası milyon başına $0.01 |
| Saklanan vektör boyutu | 5 milyon | İlk 10 milyon dahil, sonrası 100 milyon başına $0.05 |
Resmî formül:
((sorgulanan vektör + saklanan vektör) × boyut × ($0.01 / 1.000.000))
+ (saklanan vektör × boyut × ($0.05 / 100.000.000))
“You are not billed for CPU, memory, ‘active index hours’, or the number of indexes you create. If you are not issuing queries against your indexes, you are not billed for queried vector dimensions.”
Metriklerin tanımı — dikkat
“Queried Vector Dimensions: The total number of vector dimensions queried. If you have 10,000 vectors with 384-dimensions in an index, and make 100 queries against that index, your total queried vector dimensions would sum to 3.878 million (
(10000 + 100) * 384).”
“Stored Vector Dimensions: The total number of vector dimensions stored. If you have 1,000 vectors with 1536-dimensions in an index, your stored vector dimensions would sum to 1.536 million (
1000 * 1536).”
İlk formülde (10000 + 100) yazdığına dikkat et: her sorgu, index’in tamamı üzerinden
faturalanır. Index büyüdükçe sorgu başına maliyet artar.
Resmî örnek iş yükleri
| İş yükü | Boyut | Saklanan | Aylık sorgu | Tahmini toplam |
|---|---|---|---|---|
| Deneme | 384 | 5.000 vektör | 10.000 | $0.06 / ay |
| Büyüyen | 768 | 25.000 vektör | 50.000 | $0.59 / ay |
| Üretim | 768 | 50.000 vektör | 200.000 | $1.94 / ay |
| Büyük | 768 | 250.000 vektör | 500.000 | $5.86 / ay |
| Çok büyük | 1536 | 500.000 vektör | 1.000.000 | $23.42 / ay |
Resmî SSS’ten dört net cevap
- “Will Vectorize always have a free tier?” → “Yes, the Workers free tier will always include the ability to prototype and experiment with Vectorize for free.”
- “Does Vectorize charge for data transfer / egress?” → “No.”
- “Do queries I issue from the HTTP API or the Wrangler command-line count as billable usage?” → “Yes”
- “Does an empty index, with no vectors, contribute to storage?” → “No.”
Limitler
| Özellik | Limit |
|---|---|
| Hesap başına index | 50.000 (Paid) / 100 (Free) |
| Vektör başına maksimum boyut | 1536 boyut, 32 bit hassasiyet |
| Vektör ID uzunluğu | 64 byte |
| Vektör başına metadata | 10 KiB |
| topK (değer veya metadata ile) | 50 |
| topK (değer ve metadata olmadan) | 100 |
| Toplu upsert boyutu | 1000 (Workers) / 5000 (HTTP API) |
| list-vectors sayfa boyutu | 1000 |
| Index adı uzunluğu | 64 byte |
| Index başına maksimum vektör | 20.000.000 |
| Index başına namespace | 50.000 (Paid) / 1000 (Free) |
| Namespace adı uzunluğu | 64 byte |
| Maksimum yükleme boyutu | 100 MB |
| Index başına metadata index’i | 10 |
| Metadata index’i başına indexlenen veri | 64 byte |
Ek kısıtlar: filtre JSON’u 2048 byte altı; filtre anahtarı en fazla 512 karakter; iç toplu işleme sınırı 200.000 vektör veya 1.000 tekil güncelleme.
Lisanslama ve hukuki çerçeve
Hizmet tescillidir ve Cloudflare Hizmet Şartları’na tabidir; açık kaynak değildir, kendi altyapına kuramazsın.
Veri açısından en önemli özellik: Vectorize kaynak içeriğini saklamaz, yalnızca vektörleri ve en fazla 10 KiB metadata’yı tutar. Bu, KVKK açısından değerlendirmeyi kolaylaştırır — ancak embedding’lerin de kişisel veri olabileceğini unutma: bir embedding, üretildiği metni tam olarak geri vermez ama benzerlik araması ile bir kişiyi diğerlerinden ayırt edilebilir kılabilir. Kişisel veri içeren metinlerden üretilmiş vektörleri, kaynak metinle aynı hukuki rejime tabi saymak güvenli yaklaşımdır.
Metadata’ya ne koyduğuna dikkat et. Metadata sorgu sonucunda geri döner ve loglanabilir. Kimlik numarası, telefon veya e-posta gibi alanları metadata’ya koymak yerine, R2 veya D1’deki kayda işaret eden bir anahtar koy.
Silme hakkı. deleteByIds() ile silme yapılabilir ama yazmalar gibi asenkron çalışır. KVKK
kapsamında bir silme talebini karşılarken, silme işleminin index’e yansıdığını
wrangler vectorize info ile doğrulaman gerekir.
Konum. Vectorize “globally distributed” olarak tanımlanıyor ve index dosyaları R2’de tutuluyor. Cloudflare, Vectorize için bölgesel yerleşim veya Data Localization Suite kapsamı konusunda hiçbir taahhüt yayımlamamıştır. Yurt dışına aktarım değerlendirmesi yaparken bunu dikkate al.
Sık yapılan hatalar
Metadata index’ini vektörlerden sonra oluşturmak. Sessizce 0 sonuç. Bu listedeki en yaygın hata.
insert ile güncelleme yapmaya çalışmak. İlk değer kalır, hata dönmez.
queryVector veya queryVector.data göndermek. Resmî ifade: “Passing queryVector or
queryVector.data will cause query() to return an error.” Doğrusu queryVector.data[0].
Tek tek insert etmek. 250.000 vektör bir saat sürer; toplu yazınca birkaç dakika.
topK’nın filtreden bağımsız olduğunu sanmak. Filtre önce çalışır.
Yüksek kardinaliteli alanı indexlemek (ms cinsinden timestamp, UUID). Hata almazsın, sadece sonuçların bozulur.
returnMetadata: 'all'’ı varsayılan yapmak. Gecikme artar ve topK 50’ye düşer. Filtre
alanları yetiyorsa 'indexed' kullan — gecikme maliyeti yok.
Aynı index’te farklı modellerin embedding’lerini karıştırmak. Boyut uysa bile skorlar anlamsız olur.
$gt + $lt dışında aralık kombinasyonu denemek. Yalnızca bir alt sınır ve bir üst sınır
birlikte kullanılabilir.
String metadata’nın tamamının filtrelenebildiğini sanmak. Yalnızca ilk 64 byte indexlenir — uzun URL’lerde veya Türkçe metinlerde (çok baytlı karakterler yüzünden) bu sandığından erken biter.
Wrangler 3.71.0’dan eski sürüm kullanmak. Sessizce V1 davranışına düşersin.
Boş index’lerin para yaktığını sanmak. Yakmaz — boyut A/B testi için üç index açmak bedava.
CLI ve HTTP sorgularının faturaya girmediğini sanmak. Girer.
Sıkça sorulan sorular
- Vectorize ücretsiz planda çalışıyor mu?
- Evet. Workers Free planında ayda 30 milyon sorgulanan ve 5 milyon saklanan vektör boyutu ücretsiz. Dikkat: Workers fiyatlandırma sayfasında hâlâ “Vectorize is currently only available on the Workers paid plan.” cümlesi duruyor — bu cümle yanlış. Aynı sayfadaki tablo Workers Free sütununu dolu gösteriyor, Vectorize'ın kendi dokümanı “Vectorize is available to all users on the Workers Free or Paid plans” diyor ve 16 Eylül 2024 changelog'u ücretsiz plana açılışı duyuruyor.
- Index oluşturduktan sonra boyutu veya metriği değiştirebilir miyim?
- Hayır. Resmî ifade: “The configuration of an index cannot be changed after creation.” Yeni bir index açıp tüm korpusu yeniden embed etmek zorundasın. İyi haber: silinen bir index'in adı yeniden kullanılabilir (Aralık 2024'ten beri), yani geçiş sırasında adı koruyabilirsin. pgvector'ün
ALTEResnekliği burada yok. - Insert ettim ama sorgu boş dönüyor, neden?
- Yazmalar asenkron. Resmî ifade: “It typically takes a few seconds for inserted vectors to be available for querying.” Doğrulamak için
npx wrangler vectorize info <index>çalıştır veprocessedUpToMutationalanının, insert'in döndürdüğümutationIdile eşleşmesini bekle. Kullanıcı bir belge yükleyip hemen aratıyorsa, arayüzde bekleme durumu göstermen gerekir. - Metadata filtresi çalışmıyor ama hata da vermiyor.
- En sık yapılan hata bu. Metadata index'ini vektörleri eklemeden önce oluşturman gerekiyor. Resmî ifade: “Vectors upserted before a metadata index was created won't have their metadata contained in that index. Upserting/re-upserting vectors after it was created will have them indexed as expected.” Sonuç: sessizce
count: 0dönersin. Çözüm aynı id'lerle yenidenupsertyapmak. - topK 10 verdim ama 3 sonuç döndü.
- Bu bir hata değil, tasarım. Resmî ifade: “`filter` is applied first, and the `topK` results are taken from the filtered set.” Filtre önce çalışır; filtrelenmiş kümede 10 aday yoksa daha az sonuç alırsın. Aynı sebeple, filtre uygulandığında normalde ilk 10'a giremeyecek düşük skorlu bir kayıt listeye girebilir.
- Fatura neden beklediğimden yüksek?
- Çünkü “sorgulanan vektör boyutu” metriği sandığın gibi hesaplanmıyor. Resmî örnek: “If you have 10,000 vectors with 384-dimensions in an index, and make 100 queries against that index, your total queried vector dimensions would sum to 3.878 million ((10000 + 100) * 384).” Yani formül (saklanan vektör + sorgu sayısı) × boyut. Her sorgu, tüm index'i taramış gibi faturalanır. 1 milyon vektörün varsa tek bir sorgu bile 1.000.001 × boyut olarak sayılır.
- topK neden 50'de takılıyor?
returnValues: trueveyareturnMetadata: "all"kullandığında üst sınır 50. İkisini de kapatırsan 100'e çıkar. Resmî ifade: “for a query operation with returnValues set to true or returnMetadata set to all, topK is limited to a maximum value of 50.”- <code>insert</code> mi <code>upsert</code> mi kullanmalıyım?
- Neredeyse her zaman
upsert. Aynı id ileinsertilk değeri korur,upsertson değeri yazar — veinserthata da vermez, sessizce eskiyi bırakır. Bir uyarı daha: “Upserting does not merge or combine the values or metadata of an existing vector with the upserted vector: the upserted vector replaces the existing vector in full.” Yani sadece metadata güncellemek için vektörü de göndermen gerekir. - 250.000 vektörü nasıl hızlı yüklerim?
- Toplu yükle. Cloudflare'in kendi örneği çarpıcı: tek tek 250.000 çağrı yaparsan “This could take at least an hour to do.” Aynı veriyi 2.500'lük 100 dosyaya bölersen “Vectorize would update the index in only 2 or 3 jobs. All 250,000 vectors will visible in queries within minutes.” Sebep, iç toplu işleme sınırı: “the maximum size of a batch to 200,000 total vectors or to 1,000 individual updates, whichever limit it hits first.” HTTP API'de dosya başına en fazla 5000 vektör kullan.
- Kaç tenant'ı tek index'te barındırabilirim?
- Workers Paid'de index başına 50.000 namespace. Multi-tenancy için namespace metadata filtresine tercih edilmeli, çünkü “A namespace filter is applied before metadata filter(s)” ve “Namespace filtering is applied before vector search, increasing the precision of the matched results.” Yani hem daha hızlı hem daha güvenli. Dikkat: bir vektör yalnızca tek bir namespace'e ait olabilir. Not:
insert-vectorssayfası hâlâ eski 1.000 sınırını yazıyor; limit sayfası ve 24 Ekim 2024 changelog'u 50.000 diyor. - Türkçe içerik için hangi embedding modeli?
- Workers AI'ın
@cf/baai/bge-*-en-v1.5modelleri İngilizce için eğitilmiş — Türkçe korpusta bunları varsayılan yapma. Çok dilli seçenek@cf/baai/bge-m3(1024 boyut, milyon token $0.012). Vectorize modelden bağımsızdır; OpenAI veya Cohereembed-multilingual-v2.0(768 boyut) de kullanabilirsin. Cloudflare Türkçe için kalite ölçümü yayımlamıyor, kendi gold set'ini kurman gerekiyor. - Boş index'ler para yakar mı? Kaç index açabilirim?
- Yakmaz. Resmî ifade: “Empty indexes do not count as stored vector dimensions.” Ve “You are not billed for CPU, memory, ‘active index hours’, or the number of indexes you create.” Ücretli planda hesap başına 50.000 index açabilirsin. Bu, boyut A/B testi yapmayı ücretsiz kılar — üç farklı boyutta üç index açıp karşılaştırmak hiçbir ek maliyet doğurmaz.
- CLI'dan veya HTTP API'den yaptığım sorgular faturaya giriyor mu?
- Evet. Resmî SSS: “Do queries I issue from the HTTP API or the Wrangler command-line count as billable usage? Yes: any queries you issue against your index, including from the Workers API, HTTP API and CLI all count as usage.” Test ederken bunu unutma.
- Egress ücreti var mı?
- Hayır. Resmî SSS'te doğrudan soruluyor ve cevap tek kelime: “Does Vectorize charge for data transfer / egress? No.”
İlgili servisler
- Workers AIAçık kaynak modelleri Cloudflare’in GPU’larında, API çağrısıyla çalıştırır.
- AI SearchKendi belgelerin üzerinde RAG pipeline’ını (chunking, embedding, arama) hazır kurar.
- D1Workers’a bağlanan serverless SQLite veritabanı.
- R2S3 uyumlu object storage — çıkış (egress) trafiği ücretsiz.
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.