Bi saniye — Geçenlerde bir müşterimle Teams üzerinden konuşuyorduk — e-ticaret tarafında çalışan bir ekip, GPT tabanlı öneri motorunu kurmuş, RAG mimarisi de var, her şey kağıt üstünde fena durmuyor. Sonra aylık Azure faturası bir anda üç katına çıkmış. “Aşkın bey, biz neyi yanlış yaptık?” diye sordular. Faturayı açtık, baktık… Cosmos DB tarafı resmen savaş alanı. Embedding’leri saklıyorlar ama provisioned throughput modunda 100K RU/s ayırmışlar, gerçek kullanım işe pik saatlerde bile 18K civarı. Yanı gecenin 03:00’ünde de aynı parayı ödüyorlar, kimse uygulamayı kullanmasa bile. Acı ama gerçek.
İşin aslı şu ki, AI ve agentic workload’lar veri katmanındaki verimsizlikleri eski uygulamalardan çok daha hızlı ortaya çıkarıyor. Embedding sakla, düşük gecikmeyle çek, chat trafiğinin anı patlamalarını karşıla, üstüne bir de multi-region ekle… Cosmos DB doğru kurgulandığında bu yüklerin altından kalkıyor, bunu gördüm. Yanlış kurgulandığında işe para basar gıbı kullanır; yanı sistem çalışır ama fatura iç yakar.
Microsoft’un yayınladığı maliyet optimize etme white paper’ı, John Savill’in rehberleri. Sahadan gelen geri bildirimler bir araya gelince ortaya net bir tablo çıkıyor. Aşağıda 20 yılın getirdiği deneyimle, kendi müşterilerimde uyguladığım 7 pratik taktiği paylaşacağım. Birebir Microsoft tavsiyelerini tekrarlamayacağım — Türkiye’deki şirket gerçeğine de değineceğim. Çünkü teori güzel, ama ay sonu faturası daha da güzel konuşuyor.
1. Dev/Test Ortamı İçin Para Yakmayı Bırakın
En sık gördüğüm tuzak bu. Üretim ortamı henüz canlıya çıkmamış ama dev, test, UAT ortamları çoktan provisioned throughput’ta dönüyor. Üç ortam, her biri 4K RU/s minimum… bir bakmışsınız aylık 600-700 dolar gitmiş, henüz hiçbir müşteri uygulamayı görmedi bile. Garip geliyor ama oluyor.
Cosmos DB’nın Free Tier özelliği var ve her abonelik bunu bir kere alabiliyor. Aylık 1000 RU/s ve 25 GB depolama bedava. Bunun üstüne bir de Cosmos DB Emülatör var; lokal makinenizde Docker container olarak ya da direkt Windows üzerinde çalışıyor — bulutta hiç para harcamadan geliştirme yapabiliyorsunuz. Hani ne farkı var diyorsunuz, değil mi? Şey gıbı düşünün: önce mutfakta tadına bakıyorsunuz, sonra restorana açıyorsunuz.
Geçen yıl bir fintech projesinde tam bunu yaptık. Üç developer’ın laptop’unda — ki bu tartışılır — emülatör çalışıyordu, CI pipeline’da test container’ı vardı, sadece staging Free Tier’da kaldı. Toplam Cosmos DB maliyeti canlıya çıkana kadar sıfırdı. Siz ne dersiniz? Sıfır. Evet, yanlış okumadınız.
2. Throughput Modunu Doğru Seç — Ama Esnek Ol
Cosmos DB’de üç temel throughput modu var: serverless, autoscale, provisioned. Hangisini ne zaman seçeceğini bilmek tasarruf değil, baya sağlık meselesi oluyor bazen.
| Mod | Ne Zaman? | Tipik Kullanım | Maliyet Profili |
|---|---|---|---|
| Serverless | Patlama trafiği, düşük hacim | Dev, POC, düşük trafikli iç uygulamalar | Kullandığın kadar öde |
| Autoscale | Tahmin edilemeyen pik’ler | Chat uygulamaları, e-ticaret | Pik’in %10’u minimum garanti |
| Provisioned | Düzenli, tahmin edilebilir | Steady-state üretim | En ucuz ama riskli |
AI uygulamalarında genelde autoscale daha mantıklı çünkü chat trafiği saat 14:00’te patlar, 22:00’de düşer (evet, doğru duydunuz). Ama dikkat — autoscale max’ı çok yüksek koyarsanız yine cebiniz yanar. Max değeri gerçek pik’in yaklaşık 1.3 katı civarında tutun; fazlası bazen gereksiz yere şişiyor.
Novo Nordisk’in vakası ilginçti. Aylık 240 dolarlık bir database’den 1 dolarlık serverless’e geçmişlerdi. Dört ortam çarpı 240 yapar 960 dolar/ay; sonra dört dolar olmuştu işte (bu beni çok şaşırttı). Ama herkes Novo Nordisk değil tabi — eğer trafiğiniz sürekli yüksekse serverless faturanız kafanıza kafanıza vurur.
Ve işler burada ilginçleşiyor.
Türkiye Perspektifi: Kurumlar Hâlâ Provisioned Seviyor
Burada bir not düşmem lazım. Türkiye’de büyük kurumsal müşterilerle çalışırken fark ettim: finans. Telekom tarafı “tahmin edilebilir maliyet” istiyor. CFO’ya gidip “bu ay ne kadar gelir bilmiyoruz” demek zor oluyor; açık konuşayım kimse o cümleyi sevmez. Bu yüzden serverless ve autoscale teknik olarak daha mantıklı olsa bile, bir banka müşterimde provisioned + reserved capacity kombinasyonunu tercih ettik (çünkü işin muhasebe tarafı da var). 1 yıllık reserved capacity %20-25 indirim getiriyor, 3 yıllık işe %63’e kadar çıkabiliyor. Steady workload varsa kaçırmayın derim.
3. Veri Modeli: Embedding’lerinizi Doğru Saklayın
Bir hata yaptım geçenlerde — bir müşteride DiskANN yerine flat indeks bıraktık varsayılan haldeydi zaten gözden kaçtı. Sorgu RU tüketimi tavan yaptı; sonra DiskANN’a geçince RU başına maliyet %70 düştü açıkçası şaşırdım biraz. Microsoft Agent Framework’te Chat History: Nerede yazımda bahsettiğim gıbı, agent’ların geçmişini saklarken de aynı hassasiyeti gösterin; yoksa geçmiş büyüyor da büyüyor.
// Yanlış: Tüm container'ı varsayılan indekslemek
{
"indexingPolicy": {
"indexingMode": "consistent",
"includedPaths": [{ "path": "/*" }]
}
}
// Doğru: Sadece sorguladığın alanları indeksle
{
"indexingPolicy": {
"indexingMode": "consistent",
"includedPaths": [
{ "path": "/userId/?" },
{ "path": "/timestamp/?" }
],
"excludedPaths": [{ "path": "/*" }],
"vectorIndexes": [
{ "path": "/embedding", "type": "diskANN" }
]
}
}
Bu basit değişiklik bir e-ticaret müşterimde write RU tüketimini %40 düşürdü denebilir; ölçtükten sonra tablo baya netleşti çünkü her insert’te büyük çoğunluk property’leri indekslemek yerine sadece ihtiyaç olanları indeksliyor oluyorduk (küçük fark gıbı duruyor. Değil). Hani “varsayılan ayarlar genelde iyidir” derler ya — Cosmos DB’de değil işte o kadar basit değil (inanın bana)
Hmm, bunu nasıl anlatsamdı…
4. Partition Key — Hayatınızı Kurtaracak Tek Karar
Bunu yeterince vurgulayamıyorum: partition key seçimi tek başına faturanızı beş katına çıkarabilir veya 5’e bölebilir. AZ-305 sınavına hazırlanırken bu konuyu en az üç kez tekrar etmiştim; sahada yine hata görüyorum. Teoriyi bilmek yetmiyor. Kubernetes v1.36’da User Namespaces GA: Rootless Devri Geldi yazımızda bu konuya da değinmiştik.
Hot partition = bedava para basan ATM gıbı çalışır ama ters yönden bakınca can sıkıcıdır. Yanlış partition key seçtiğinizde RU tüketimi homojen dağılmaz, bir partition’a yığılır. O partition tıkanır, siz daha fazla RU satın alırsınız, diğer partition’lar boş yatar.
Klasik enterprise yangını.
AI workload’unda tipik hata şu oluyor: tüm chat geçmişini “tenantId” ile partition’lamak yapılıyor ve ilk bakışta mantıklı geliyor ama değil aslında; eğer 3-5 büyük müşteriniz varsa ve trafiğin %80’i bunlardan geliyorsa başınız belada demektir. Bunun yerine “tenantId + sessionId” gıbı composite key kullanmak daha sağlıklı oluyor çoğu senaryoda (tabi sorgu pattern’inize bağlı). Neden önemli bu? Eğer cross-session sorgu yapmıyorsanız bu iş görür.
Evet, doğru duydunuz.
Kardinalite ve Erişim Düzeni Dengesi
5. TTL Kullanın — Veri Ölmeli
BIR SaaS müşterimde tam bir yıllık birikmiş chat verisi vardı.
480 GB.
TTL’i
60 güne çekince üç hafta içinde
80 GB’a düştü.
Storage maliyeti ufak gıbı görünür. Indeksleme yükü büyük,
RU başına performans da iyileşti.
Yanı veri azaldıkça sistem rahatlıyor,
öyle garip biçimde nefes alıyor diyebilirim. Daha fazla bilgi için GPT-5.5 GitHub Copilot’ta GA: 7.5x Çarpan Değer mi? yazımıza bakabilirsiniz.
- 30-60 gün TTL idare eder
-
7-14 gün,
gerisini Storage Account’a arşivle -
7 gün —
dokümanlar değişiyorsa eski embedding zaten geçersiz -
24 saat,
çoğu durumda yeter
Bakın, burayı atlarsanız yazının kalanı anlamsız kalır. Yeni GitHub PR Dashboard: Artık Varsayılan Geliyor yazımızda bu konuya da değinmiştik.
Bence, Bunu söylediğimde ekipler bana inanmıyor:
aynı veriyi getiren iki sorgu arasında olabiliyor.
SELECT * yazıp gitmek lüks,
alanı belirtmek hayat kurtarıyor.
Bu kadar mı?
Değil tabii,
ama başlangıç için iyi yer burası.Saniyede
200 request gelen bir endpoint için yıllık fatura farkı yaklaşık
14.000 dolar.
Üç satır kod değişikliği,
işte olay bu kadar sadeleşebiliyor bazen.
7. Multi-Region: İhtiyacınız Var mı, Gerçekten?
Bunu yaşayan biri olarak söyleyeyim, Açık konuşayım:
multi-region writes maliyeti ikiye,
üçe katlıyor.
Eğer aktif-aktif global bir uygulamanız yoksa,
single-write region + multiple read regions size yeter de artar.
Yanı önce ihtiyacı doğrulayın,
sonra mimariyi şişirin. Daha fazla bilgi için JetBrains Copilot: Inline Agent Mode ve Yeni Oyuncaklar yazımıza bakabilirsiniz.
Azure MCP Server.mcpb Paketi:
Runtime Derdine Veda yazısında değindiğim gıbı,
infrastructure ‘ı sade tutmak operasyonel maliyeti de düşürüyor.
Multi-region tasarımı abartmak hem para hem zaman kaybı.
İşin özü bu kadar net bazen. Bu konuyla ilgili Entra External ID Native Auth: SSO ile WebView Köprüsü Geldi yazımıza da göz atmanızı tavsiye ederim.
Pratik Aksiyon Listesi:
Bu Hafta Yapın
- Azure Portal ‘da Cosmos DB Insights’a girin,
son
7 günün RU kullanımını çıkarın - Provisioned throughput’ünüz pik’in
2 katından fazlaysa,
autoscale’a geçin - Tüm container ‘ların indexing policy’sını gözden geçirin,
gereksiz alanları exclude edin - RU charge ‘ı en yüksek
5 sorguyu bulun,
partition key kullanıp kullanmadıklarını kontrol edin - 30 günden eski geliştirme ortamlarına TTL ekleyin veya silin — bunu es geçmeyin
Bütçeniz Kısıtlıysa: Alternatif Senaryolar
tek başına yetebilir.
Hatta PostgreSQL + pgvector kombinasyonu çok daha ucuza çıkıyor —
Azure Database for PostgreSQL Flexible Server’da pgvector eklentisi var,
aylık
50 -100 dolara fena olmayan bir vektör DB kuruyorsunuz.
Bazen sadelik kazanıyor, evet.
Şöyle ki, Cosmos DB ‘yi şu durumlarda tercih edin:
global dağıtım,
milisaniye altı gecikme,
milyon+ vektör,
NoSQL esnekliği. Bunlar yoksa,
daha sade bir çözüm hem cebinize hem operasyonel yükünüze iyi gelir. Neyse uzatmayayım;
önce ihtiyacı doğru okuyun, sonra servisi seçin.
Sıkça Sorulan Sorular
Cosmos DB’de RU/s ne oluyor, nasıl hesaplıyoruz?
Araya gireyim: Request Unit (RU), hani 1 KB’lık bir dokümanı okumak için harcanan kaynak miktarı aslında. Yazma işlemi genellikle 5-6 RU tutuyor, sorgu tarama yapıyorsa 100+ RU’ya çıkabiliyor (yanlış duymadınız). Saniyedeki RU tüketiminizi Application Insights ya da Cosmos DB Metrics üzerinden takıp edebilirsiniz. Tecrübeme göre her sorgunun RequestCharge property’sını mutlaka log’a basın — sonradan çok işinize yarıyor.
Serverless mi seçeyim, autoscale mi?
Aylık 1 milyon işlemin altındaysanız ve trafik epey düzensizse serverless mantıklı. 1M’in üstündeyseniz ya da tahmin edilebilir pik’leriniz varsa autoscale daha iyi oturuyor. Bence steady workload’da reserved capacity ile provisioned en ucuz çözüm —. Açıkçası esnekliği biraz feda ediyorsunuz, bunu göz önünde bulundurun.
Embedding’leri nerede saklayayım, Cosmos DB mi Azure AI Search mi?
Yanı aynı veri üzerinde hem operasyonel sorgu hem de vektör arama yapacaksanız Cosmos DB her şeyi tek çatı altında topluyor. Sadece arama yapacaksanız ve doküman sayınız fazla değilse Azure AI Search daha ucuza geliyor. Hibrit senaryolarda ikisini birlikte kullanmak aslında çok yaygın — mesela Cosmos DB ana kaynak, AI Search da arama katmanı olarak konumlanıyor.
Reserved capacity’yi ne zaman almam lazım?
İnanın, En az 3 ay üst üste stabil bir RU kullanımınız varsa ve uygulama production’da iyice yerleşmişse, 1 yıllık reserved capacity %20-25 indirim getiriyor (evet, doğru duydunuz). Ama yeni başlayan projelerde almayın bence — workload değişebilir, taahhüdü iptal edemiyorsunuz, sonra pişman olabilirsiniz.
Hot partition sorununu nasıl anlayabilirim?
İlginç olan şu ki, Azure Portal’da Cosmos DB > Insights > Throughput bölümüne gidin, orada “Normalized RU Consumption by PartitionKeyRangeId” diye bir grafik var. Eğer bir partition diğerlerinden belirgin şekilde bir düşüneyim… yüksek görünüyorsa, işte orada hot partition var demektir. %66’nın üstü kronik bir problem sayılıyor — açıkçası bu noktada partition key tasarımını baştan gözden geçirmek gerekiyor.
Kaynaklar ve İleri Okuma
7 tips to optimize Azure Cosmos DB costs for AI and agentic workloads – Microsoft DevBlogs
Şöyle ki, Azure Cosmos DB Throughput Optimization – Microsoft Learn (ben de ilk duyduğumda şaşırmıştım)
Vector Search in Azure Cosmos DB for NoSQL – Microsoft Learn
Azure Cosmos DB Pricing Details (kendi tecrübem)
Bu içerik işinize yaradı mı?
Benzer içerikleri kaçırmamak için beni sosyal medyada takip edin.



