Multi-tenant SaaS mimarisi, tek bir yazılım kopyasının onlarca hatta binlerce müşteriye (tenant) aynı anda hizmet verdiği bir yapıdır. Bu model maliyet avantajı sağlar ama beraberinde veri yalıtımı, performans eşitsizliği ve özelleştirme sınırları gibi kritik kararlar getirir. Bu yazıda bir SaaS platformu kurarken karşılaşacağınız mimari seçimleri — veritabanı paylaşım modelinden, tenant başına kaynak sınırlamalarına, güvenlik açıklarından, ölçekleme stratejilerine kadar — somut örnekler ve uygulanabilir karar kurallarıyla ele alacağız. Hangi modelin ne zaman mantıklı olduğunu, yanlış seçimin ne tür sorunlara yol açtığını ve production ortamında sizi ne tür sürprizlerin beklediğini bu yazıda bulacaksınız.
Tek Kaynak, Çok Kiracı: Mimarinin Temel Mekaniği
Multi-tenant bir sistemde her tenant kendi bağımsız uygulama kopyasını çalıştırmaz; tüm müşteriler aynı uygulama sunucusu, aynı kod tabanı ve çoğu durumda aynı veritabanı altyapısı üzerinden hizmet alır. Temel fark, her isteğin hangi tenant'a ait olduğunun tanımlanmasıdır. Bu tanımlama genellikle oturum token'ı içindeki tenant_id alanı ya da alt alan adı (örneğin musteriadi.uygulama.com) üzerinden yapılır. Uygulama katmanında her veri sorgusuna otomatik olarak tenant filtresi eklenir.
Uzman bakışı açısıyla burada en sık gözden kaçan nokta, "shared everything" modelinin ekonomik avantajının ardındaki operasyonel karmaşıktır. Tek bir veritabanında milyonlarca satırı tenant bazlı filtrelemek, indeks stratejinizi doğrudan etkiler. Mikro örnek olarak düşünün: Türkiye'de faaliyet gösteren bir e-ticaret SaaS'ında 200 farklı mağaza aynı veritabanını paylaşıyor. Bir mağaza yüksek trafikli bir kampanya başlattığında, sorguları tüm havuzu yavaşlatabilir — buna "noisy neighbor" problemi denir. Karar kuralı: Tenant sayınız 50'yi geçmeden önce veri tabanı indeksleme ve bağlantı havuzu (connection pool) stratejinizi tenant bazlı simülasyonlarla test edin.
Veri Yalıtım Modelleri: Üç Yolun Maliyet ve Güvenlik Dengesi
Veritabanı tasarımında üç temel model vardır. Her tenant'a ayrı veritabanı (database-per-tenant) en güçlü yalıtımı sağlar; bir müşterinin verisine erişim diğerini hiç etkilemez. Ancak 200 tenant için 200 veritabanı yönetmek, backup, migration ve monitoring maliyetlerini katlar. Paylaşımlı veritabanı, ayrı şema (schema-per-tenant) modelinde her tenant kendi şemasında tablolara sahiptir; yalıtım güçlüdür ama şema sayısı arttıkça yönetim yükü büyür. Tek veritabanı, tek şema, filtreleme (shared everything) en ucuz seçenektir; tüm veri aynı tablolarda tenant_id ile ayrılır. Bu modelde tek bir indeks eksikliği ya da filtre unutulması, tüm müşterilerin verisini riske atabilir.
Gerçek dünyadan bir örnek: B2B CRM hizmeti veren bir SaaS şirketi, başlangıçta shared-everything modeliyle yola çıktı. İlk 30 müşteri sorunsuz çalıştı. Ancak bir finans müşterisi SOC 2 denetimi sırasında "verilerimizin fiziksel olarak ayrıştırılmış olmasını" talep etti. Şirket, tek bir müşteriyi ayrı veritabanına taşımak için üç haftalık bir refactoring süreci yaşadı. Karar kuralı: Hedef kitleniz regülasyona tabi sektörlerse (finans, sağlık, kamu), en azından schema-per-tenant modeliyle başlayın; ileride database-per-tenant'a geçiş maliyeti dramatik şekilde düşer.
Noisy Neighbor Problemi ve Kaynak Yönetim Stratejileri
Multi-tenant mimarinin en kritik operasyonel sorunu, bir tenant'ın aşırı kaynak tüketiminin diğerlerini etkilemesidir. Bu etki üç katmanda ortaya çıkar: CPU/bellek kullanımı, veritabanı sorgu trafiği ve ağ bant genişliği. Çözüm, her tenant için "resource budget" tanımlamaktır. Uygulama katmanında rate limiting (istek sınırı), veritabanında query timeout ve bağlantı havuzu kotası, altyapıda ise Kubernetes namespace bazlı resource quota uygulanabilir.
Somut bir senaryo: B2B faturalama SaaS'ınız var ve bir müşteriniz ay sonunda 50.000 fatura toplu oluşturuyor. Bu işlem 15 dakika boyunca veritabanına sürekli yazma yapıyor ve aynı sunucudaki diğer 200 müşterinin fatura listeleme sorguları 8 saniyeye kadar yavaşlıyor. Çözüm, toplu işlemleri kuyruk tabanlı (message queue) arka plan işlemine almak ve her tenant için eşzamanlı veritabanı bağlantı sayısını üst sınırla belirlemektir. Karar kuralı: Tenant başına CPU ve bellek kotasını production'a çıkmadan önce, en yüksek kullanım yapan beş tenant'ın verileriyle stres testi yapın. Limit koymadan deploy etmek, bir müşterinin tüm platformu kilitlemesi anlamına gelir.
Güvenlik Yüzeyi: Tek Hatayla Tüm Müşterileri Etkileme Riski
Multi-tenant sistemlerde güvenlik riski, tek-tenantlı uygulamalara göre geometrik olarak artar. Tek bir SQL sorgusundaki tenant_id filtresinin unutulması, tüm müşterilerin birbirinin verisini görmesi anlamına gelir. Bu tür hataları önlemek için veri erişim katmanında (ORM veya repository pattern) tenant filtresini merkezi ve zorunlu hale getirmek gerekir. Django'da custom manager, Java Spring'de Hibernate filter, Node.js'te middleware tabanlı otomatik filtreleme bu işi üstlenir.
Bir güvenlik olayı örneği: 2019'da bir Avrupa SaaS sağlayıcısında, bir API endpoint'indeki filtre unutulması nedeniyle A müşterisi, B müşterisinin 12.000 kaydını görüntüleyebildi. Olay GDPR kapsamında veri ihlali olarak raporlandı ve şirket para cezası aldı. Teknik kökeni, o endpoint'e ait unit test'in yalnızca "veri geliyor mu" sorusunu kontrol etmesi, "doğru tenant'ın verisi geliyor mu" sorusunu test etmemesiydi. Karar kuralı: Her API endpoint'i için mutlaka "cross-tenant access" testi yazın. Tenant A'nın token'ı ile Tenant B'nin verisine erişim denenmeli ve 403/404 dönmeli. Bu test, CI/CD hattında otomatik çalışmalıdır.
Tenant Bazlı Özelleştirme: Konfigürasyon mu, Kod mu?
SaaS ürününüz büyüdükçe her müşteri farklı alanlar, farklı iş kuralları, farklı entegrasyonlar isteyecek. Bu noktada iki yol vardır: konfigürasyon tabanlı özelleştirme (feature flags, dinamik form alanları, kural motorları) ya da kod tabanlı fork (tenant'a özel modül veya branch). Konfigürasyon tabanlı yaklaşım sürdürülebilir ama sınırlıdır; her yeni özellik uzun geliştirme süresi gerektirir. Kod tabanlı fork hızlı teslim edilir ama bakım maliyeti her fork ile üstel olarak artar.
Pratik bir karşılaştırma: Satış ekibiniz bir kurumsal müşteriye "bizim sistemde özel bir onay akışı var" dedi. Geliştirici iki seçenekle karşılaşır — ya genel bir iş akışı motoru (workflow engine) inşa edip müşterinin kurallarını JSON/yapılandırma dosyasıyla tanımlar (iki hafta geliştirme, sonsuza kadar esneklik) ya da o müşteriye özel bir modül yazar (üç gün geliştirme, sonsuza kadar bakım yükü). İlk müşteride fark önemsiz görünür ama 50. müşteride her birine ayrı modül yazan ekip, teknik borç altında ezilir. Karar kuralı: Özelleştirme taleplerini kategorize edin. Yüzde 80'i yapılandırma dosyası ile çözülebilecek türdense workflow motoru yatırımına erken başlayın. Sadece yüzde 5'inin gerçekten farklı kod gerektirdiğini göreceksiniz.
Sonuç: Doğru Model, Doğru Aşamada
Multi-tenant SaaS mimarisi, doğru kararlar alındığında hem maliyet hem operasyonel verimlilik açısından güçlü bir modeldir. Ancak bu kararlar sabit değildir; erken aşamada shared-everything ile başlayıp ölçekle birlikte kademeli olarak daha güçlü yalıtım modellerine geçmek sağlıklıdır. Veri güvenliği tarafında tenant filtresini merkezi ve test edilebilir kılmak, tek bir hata ile tüm müşteri tabanını riske atmanın önündeki en güçlü savunmadır. Kaynak yönetiminde noisy neighbor sorununu proaktif ele almak — kuyruk tabanlı işlem, bağlantı havuzu limiti, rate limiting — production'da sizi büyük krizlerden korur. Son olarak özelleştirme stratejinizi erken belirleyin: yapılandırma tabanlı esneklik, kod tabanlı fork'a göre katlanarak daha sürdürülebilir bir yol sunar. Hangi modeli seçerseniz seçin, test edin, ölçün ve aşamalı geçiş planınızı baştan çizin.