Bir üretim firmasının ERP’sinde çalışırken, multi-tenant mimarinin başlangıçta ne kadar cazip göründüğünü, ancak uzun vadede nasıl beklenmedik maliyetler doğurduğunu defalarca gördüm. Yönetim genellikle ilk lisanslama ve altyapı maliyetlerine odaklanır, ama operasyonel yük, güvenlik riskleri ve performans sorunları gibi görünmez giderler çoğu zaman gözden kaçar.
Bu yazıda, multi-tenant bir ERP çözümünün gerçek maliyetlerini, teknik ve operasyonel zorluklarını kendi deneyimlerimle ele alacağım. Seçim yaparken sadece başlangıç maliyetlerine değil, uzun vadeli sürdürülebilirliğe ve ekiplerin üzerindeki yüke de bakmak gerektiğini düşünüyorum.
Başlangıçtaki Cazibe: Neden Multi-Tenant?
Multi-tenant mimari, birden fazla müşterinin (tenant) tek bir yazılım örneğini ve aynı altyapıyı paylaşmasına olanak tanır. Genellikle SaaS (Software as a Service) modellerinde tercih edilir çünkü kaynakları verimli kullanma ve maliyetleri düşürme vaadiyle gelir. Örneğin, aynı PostgreSQL sunucusunda farklı şemalar veya tablolarla birden çok müşterinin verisini barındırabilirsin.
Benim üretim ERP’si projesinde de başlangıçta bu modelin cazibesine kapılmıştık. Düşük başlangıç maliyeti, hızlı deployment imkanı ve ölçeklenebilirlik potansiyeli, özellikle küçük ve orta ölçekli işletmeler için kulağa çok hoş geliyordu. Tek bir altyapıyı yöneterek yüzlerce müşteriye hizmet verebileceğimizi düşünüyorduk, bu da ilk bakışta operasyonel yükü azaltacak gibi duruyordu.
Veri İzolasyonu ve Güvenlik: Görünmeyen Riskler
Multi-tenant mimarinin belki de en kritik ve en çok göz ardı edilen yönü, veri izolasyonu ve güvenliktir. Her ne kadar aynı altyapıyı paylaşsan da, her bir tenant’ın verisinin diğerinden tamamen izole ve güvende olması şarttır. Benim kariyerimde, bu konuda yapılan yanlış bir tasarımın ne kadar büyük bir krize yol açabileceğini gördüm. Bir keresinde, yanlış bir sorgu optimizer ayarı yüzünden, bir tenant’ın raporunda kısa bir süre için başka bir tenant’ın ürün bilgileri göründü. Neyse ki, bu durum erken fark edildi ve büyük bir felaket olmadan çözüldü, ama olası itibar kaybı ve yasal sorunlar beni fazlasıyla düşündürdü.
Veri izolasyonunu sağlamak için birden fazla strateji var: ayrı veritabanları, ayrı şemalar, paylaşımlı şemada tenant ID ile filtreleme veya Row-Level Security (RLS) kullanmak. Bizim üretim ERP’sinde, başlangıçta tenant ID ile filtreleme ve daha sonra RLS entegrasyonuna geçiş yaptık. RLS, PostgreSQL 9.5 ve sonraki sürümlerinde oldukça güçlü bir mekanizma sunuyor, ancak bunu doğru yapılandırmak ve her sorguda çalıştığından emin olmak ciddi bir mühendislik eforu gerektiriyor. Ayrıca, audit loglarını tutmak ve her tenant’ın verisine kimin, ne zaman eriştiğini izlemek de başlı başına bir operasyonel yüktür.
-- PostgreSQL'de Row-Level Security (RLS) örneği
-- Policy oluşturmadan önce RLS'i etkinleştir.
ALTER TABLE orders ENABLE ROW LEVEL SECURITY;
-- Tenant ID'ye göre erişimi kısıtlayan policy
CREATE POLICY tenant_isolation_policy ON orders
USING (tenant_id = current_setting('app.current_tenant_id')::int);
-- Uygulama tarafında tenant ID'yi set etmek
SET app.current_tenant_id = 123;
-- Bu noktadan sonra, 'orders' tablosuna yapılan tüm sorgular
-- otomatik olarak tenant_id = 123 ile filtrelenir.
Bu tür mekanizmalar, doğru uygulandığında güvenliği artırır ancak aynı zamanda veritabanı performansına ek yük getirebilir ve kompleks sorgularda beklenmedik davranışlara neden olabilir. Özellikle ORM kullanırken RLS’in nasıl davrandığını iyi anlamak gerekiyor. Aksi takdirde, ORM trap’leri yazımda bahsettiğim N+1 sorgu gibi performans sorunları yaşayabilirsin.
Performans ve Kaynak Yönetimi: Tek Bir ‘Kötü Komşu’ Yeter
Multi-tenant mimarinin en büyük handikaplarından biri, kaynakların paylaşımlı olmasından kaynaklanan performans dalgalanmalarıdır. Tek bir tenant’ın yaptığı yoğun bir işlem, aynı fiziksel sunucuyu veya veritabanı örneğini kullanan diğer tüm tenant’ları etkileyebilir. Ben buna “kötü komşu sendromu” diyorum. Bir keresinde, yeni bir müşterimiz büyük bir veri aktarımı başlattı ve bu, bir süreliğine tüm ERP sisteminde raporlama ve veri giriş sürelerini gözle görülür şekilde uzattı.
Bu durumu yönetmek için kaynak izolasyonu ve limitleri tanımlamak zorundayız. Cgroup’lar Linux’ta bu konuda güçlü bir araç sunar. Her bir tenant’ı kendi cgroup’una atayarak CPU, bellek ve I/O kaynaklarına limitler getirebiliriz. Ancak, bu yapılandırma ve izleme süreci oldukça karmaşıktır. Örneğin, bir tenant’ın memory.high limitini yumuşak bir limit olarak belirleyebilirsin, bu sayede sistem kriz anlarında diğer tenant’ları öldürmeden önce bu tenant’ı yavaşlatmayı dener.
# Bir cgroup oluşturma ve limitler atama örneği
# /sys/fs/cgroup/memory/tenant_A dizinini varsayalım
sudo mkdir /sys/fs/cgroup/memory/tenant_A
sudo sh -c "echo 200M > /sys/fs/cgroup/memory/tenant_A/memory.limit_in_bytes" # 200MB hard limit
sudo sh -c "echo 180M > /sys/fs/cgroup/memory/tenant_A/memory.high" # 180MB soft limit
sudo sh -c "echo 100000 > /sys/fs/cgroup/memory/tenant_A/memory.kmem.limit_in_bytes" # Kernel memory limit
sudo sh -c "echo <process_id> > /sys/fs/cgroup/memory/tenant_A/tasks" # Process'i cgroup'a ekle
# CPU limitleri için cpu cgroup'u
sudo mkdir /sys/fs/cgroup/cpu/tenant_A
sudo sh -c "echo 100000 > /sys/fs/cgroup/cpu/tenant_A/cpu.cfs_period_us" # 100ms periyot
sudo sh -c "echo 20000 > /sys/fs/cgroup/cpu/tenant_A/cpu.cfs_quota_us" # 20ms CPU kullanımı (20% CPU)
Bu tür detaylı cgroup ayarları, sistem yöneticisi olarak bana ciddi bir ek yük getirdi. Her tenant’ın kaynak tüketimini ayrı ayrı izlemek, anomali tespiti yapmak ve gerektiğinde manuel müdahalede bulunmak zorundaydım. Bu, tek bir veritabanı veya uygulama sunucusu yerine, her tenant’ın kendi izole altyapısına sahip olduğu bir single-tenant modelinde karşılaşmayacağın bir karmaşıklıktır. Özellikle PostgreSQL performans regresyonları yaşadığımızda, hangi tenant’ın soruna yol açtığını bulmak bazen günlerimizi alıyordu.
Özelleştirme ve Sürüm Yönetimi: Esnekliğin Bedeli
Her ERP müşterisinin kendine özgü iş akışları ve raporlama ihtiyaçları vardır. Multi-tenant bir yapıda, her müşteriye özel bir geliştirme yapmak, genel codebase’i sürdürülemez hale getirebilir. Biz bu durumu feature flag’ler ve modüler mimari ile çözmeye çalıştık. Yani, bir özelliğin belirli bir tenant için açılıp kapanmasını sağlayan anahtarlar kullandık. Örneğin, bir müşteri için özel bir “üretim planlama algoritması” geliştirdiğimizde, bunu sadece o tenant için etkinleştiren bir feature flag ekledik.
Ancak, bu yaklaşım bile sürüm yönetimini ve test süreçlerini ciddi şekilde karmaşıklaştırdı. Her yeni sürüm çıktığında, yüzlerce farklı tenant kombinasyonunu test etmek, regresyon riskini artırıyordu. Bir tenant için yapılan bir özelleştirme, yanlışlıkla başka bir tenant’ın sistemini bozabilir. Bu yüzden deployment stratejilerimizi (blue-green, canary) ve rollback otomasyonumuzu sürekli geliştirmek zorunda kaldım.
Bu da beni, yazılım mimarisinin çoğu zaman yazılım değil, organizasyonel akış olduğu çıkarımına götürdü. Bir özelliği eklemeden önce, bu özelliğin diğer tenant’ları nasıl etkileyeceğini, test süreçlerini nasıl uzatacağını ve operasyonel yükü nasıl artıracağını çok iyi düşünmek gerekiyordu. Aksi takdirde, küçük bir özelleştirme talebi, aylarca süren bir geliştirme ve test döngüsüne dönüşebilirdi.
Operasyonel Karmaşıklık: Destek ve Hata Ayıklama Kabusu
Bir multi-tenant ERP’yi işletmek, tek bir ERP’yi işletmekten çok daha karmaşıktır. Destek ekibinin bir sorunla karşılaştığında, bunun hangi tenant’tan kaynaklandığını hızlıca tespit etmesi, diğer tenant’ların etkilenip etkilenmediğini anlaması ve sorunu izole edip çözmesi gerekir. Bu durum, özellikle yüksek hacimli bir sistemde, loglama ve izleme (observability) altyapısının çok sağlam olmasını gerektirir.
Benim deneyimimde, merkezi bir log toplama sistemi (örneğin ELK Stack veya Loki) ve dağıtık izleme (distributed tracing) olmadan multi-tenant bir sistemi yönetmek neredeyse imkansızdı. Her isteğin bir tenant_id ile etiketlenmesi, tüm servisler arasında bu tenant_id’nin geçirilmesi ve her log kaydında bu bilginin bulunması gerekiyordu. Aksi takdirde, bir hata mesajı gördüğümüzde, “Bu hata hangi müşteriyi etkiliyor?” sorusunun cevabını bulmak saatler sürüyordu.
{
"timestamp": "2026-05-17T10:30:00Z",
"level": "ERROR",
"service": "order-processing",
"tenant_id": 456,
"transaction_id": "abc-123-xyz",
"message": "Failed to update inventory for product SKU: P-789. Stock is negative.",
"user_id": 7890
}
Yukarıdaki gibi detaylı log kayıtları bile, bir üretim ortamında yüzlerce tenant’ın aynı anda işlem yaptığı durumlarda, bir sorunu izole etmek için yeterli olmayabiliyor. Özellikle sistemde bir yavaşlama olduğunda, hangi tenant’ın, hangi işleminin soruna neden olduğunu bulmak için metrikleri, logları ve trace’leri aynı anda analiz etmek zorunda kalıyordum. Bu da operasyon ekibimizin üzerindeki yükü kat be kat artırıyordu.
Maliyet Hesaplamasının Perde Arkası: Gerçek TCO
Sonuç olarak, multi-tenant ERP çözümlerinin ilk bakışta sunduğu maliyet avantajı, genellikle operasyonel, güvenlik, performans ve özelleştirme gibi görünmez maliyetlerle dengelenir. Birçok şirket, Total Cost of Ownership (TCO) hesaplamalarını yaparken bu gizli kalemleri yeterince dikkate almaz. Benim gördüğüm kadarıyla, bir multi-tenant sistemin uzun vadeli maliyeti, bazen tekil (single-tenant) sistemlerin maliyetini bile aşabilir.
Bu gizli maliyetler şunları içerebilir:
- Ek Personel Giderleri: Daha karmaşık bir sistemin yönetimi, daha fazla deneyimli sistem yöneticisi ve destek personeli gerektirir.
- Gelişmiş İzleme ve Güvenlik Araçları: Merkezi loglama, dağıtık izleme, gelişmiş güvenlik duvarları ve SIEM (Security Information and Event Management) sistemleri için ek yatırımlar.
- Daha Uzun Geliştirme Süreçleri: Özelleştirmelerin ve yeni özelliklerin multi-tenant mimariye uygun hale getirilmesi için harcanan ekstra mühendislik zamanı.
- Artan Test Yükü: Her güncelleme ve özelleştirme için daha kapsamlı ve karmaşık test senaryoları.
- Daha Yüksek Altyapı Maliyetleri: Kötü komşu sendromunu engellemek veya performans sorunlarını gidermek için gereğinden fazla kaynak ayırmak zorunda kalmak.
Bir projemde, birkaç yıl içinde multi-tenant yapının getirdiği ek operasyonel maliyetlerin, başlangıçtaki lisans ve altyapı tasarruflarını belirgin biçimde aştığını gördük. Bu, başlangıçta öngörülenin çok üzerinde bir farktı.
Sonuç: Tercihimi Neye Göre Yapıyorum?
Multi-tenant mimari, doğru senaryoda ve doğru tasarımla harikalar yaratabilir, özellikle standartlaşmış, az özelleştirme gerektiren ve yüksek hacimli B2C uygulamalarında. Ancak ERP gibi iş süreçlerinin karmaşık ve özelleştirme ihtiyacının yüksek olduğu kurumsal uygulamalarda, ben genelde daha dikkatli yaklaşıyorum. Benim tercihim, mümkünse single-tenant veya hybrid bir yaklaşım oluyor. Özellikle kritik iş süreçleri ve hassas veriler söz konusu olduğunda, veri izolasyonu ve performans üzerindeki tam kontrol, benim için başlangıçtaki “maliyet avantajından” çok daha değerli.
Net pozisyonum şu: Bir multi-tenant ERP çözümü değerlendirirken, sadece lisans ve ilk kurulum maliyetlerine bakmayın. Olası operasyonel yükleri, güvenlik risklerini, performans dalgalanmalarını ve özelleştirme kısıtlarını iyi analiz edin. Kendi deneyimlerime dayanarak söyleyebilirim ki, kağıt üzerindeki avantajlar, gerçek dünyada hızla eriyebilir. Gelecekte bir organizasyonel akışın yazılım mimarisine etkisi konusunda daha derinlemesine bir yazı yazmayı düşünüyorum.