
WebCatalog'da yıllarca web üzerindeki neredeyse her şeyi varsayılan olarak Vercel'e dağıttık. Bu projelerin çoğu Next.js kullanıyordu; dolayısıyla bu ikili doğal bir tercihti. Pazarlama sitelerimiz, ürün arayüzlerimiz, hesap ayarlarımız, geliştirici konsolumuz, kimlik doğrulama sistemimiz, yönetim araçlarımız ve API'lerimiz aşağı yukarı aynı teknoloji yığınında toplandı.
Bu yaklaşım uzun süre iyi işledi. Vercel dağıtımları kolaylaştırdı, Next.js bize verimli bir tam yığın geliştirme çatısı sundu ve ikisinin altındaki altyapıyı nadiren düşünmek zorunda kaldık.
Ancak zamanla bu kolaylık, ürünlerimizin ihtiyaçlarına uymamaya başladı.
Pazarlama sitelerimiz SSR'den (sunucu tarafında işleme) hâlâ yararlanıyordu, fakat diğer web uygulamalarımızın çoğunun buna ihtiyacı yoktu. Bunlar sıradan SPA'ler (tek sayfa uygulamaları) olabilirdi. API'lerimiz ise yerel bağımlılıkları ve uzun süre çalışan süreçleri destekleyen standart bir Node.js ortamına ihtiyaç duyuyordu. Ön uç teknoloji yığınımızdaki neredeyse her şey zaten Vite kullanıyordu. Aynı zamanda, özellikle herkese açık sitelerimize ve otomatik sistemlerden gelen trafik arttıkça, altyapı maliyetlerini görmezden gelmek zorlaşıyordu.
Önce mevcut sistemimizi optimize etmeye çalıştık. Next.js'i koruyup bir adaptör aracılığıyla Cloudflare Workers'a taşımayı değerlendirdik. Pazarlama siteleri için Astro'yu denedik. API'lerimizi kısa bir süreliğine Cloudflare Containers'a taşıdık.
Sonunda daha basit bir yapıya ulaştık: Web uygulamalarımızın çoğu artık Cloudflare Workers üzerinde Vite + TanStack Router, pazarlama sitelerimiz Cloudflare Workers üzerinde SSR ile TanStack Start, API'lerimiz ise Railway üzerinde uzun süre çalışan Node.js konteynerlerinde Hono + tRPC kullanıyor.
Geçiş, web altyapısı maliyetlerimizi yaklaşık %80 azalttı. Cloudflare güvenlik kurallarımızı sıkılaştırıp daha fazla zararlı otomatik trafiği uç noktada engelledikten sonra toplam tasarruf yaklaşık %90'a çıktı.
Geçişin uygulama çalışmalarının büyük bölümünü de başta Claude Fable 5 ve Claude Opus 5 olmak üzere yapay zekâ kodlama ajanları yürüttü. Mühendisler ise mimariyi belirledi, kısıtları tanımladı, değişiklikleri gözden geçirdi ve sonuçları doğruladı.
İşe Vercel'den Ayrılarak Başlamadık
İlk içgüdümüz mevcut düzeni optimize etmekti.
Başlamak için en belirgin yer webcatalog.io'ydu: Çok fazla herkese açık trafik alıyor, ancak sayfalarının çoğu nispeten seyrek değişiyordu. Sitenin gereğinden büyük bir bölümünün hâlâ dinamik olarak işlendiğini gördük. Bunun üzerine istemeden oluşan dinamik işlemeyi düzelttik, yoğun trafik alan rotalara ISR (Artımlı Statik Yeniden Oluşturma) ekledik, daha fazla sayfayı önbelleğe alınabilir hâle getirdik ve yüksek maliyetli site haritası işlemlerini optimize ettik.
Bu çalışmalar işe yaradı ama altta yatan sorunu da daha görünür kıldı. Nispeten statik içeriklerin neden dinamik olduğunu, buna hangi geliştirme çatısı davranışının yol açtığını ve içeriği yeniden önbelleğe alınabilir hâle getirmek için hangi mekanizmayı kullanmamız gerektiğini anlamaya giderek daha fazla zaman harcıyorduk.
Öte yandan, diğer uygulamalarımızın çoğunda bunun tam tersi geçerliydi. Hesap ayarları, geliştirici konsolu, yönetim uygulamaları ve ürün arayüzlerinin çoğu için sunucu tarafında işleme hiç gerekmiyordu. Bunlar API'lerle konuşan tarayıcı uygulamalarıydı.
O noktada soru, “Vercel faturamızı nasıl küçültürüz?” olmaktan çıkıp “Bu uygulamalar zaten Next.js ile geliştirilmiş olmasaydı ne kurardık?” sorusuna dönüştü.
Cloudflare Üzerinde Next.js'i Değerlendirdik
En az değişiklik gerektiren seçenek, Next.js'i koruyup Vercel'den Cloudflare Workers'a taşımaktı.
Bunu ciddi biçimde değerlendirdik; çünkü Next.js, adaptör katmanları aracılığıyla Cloudflare üzerinde çalışabiliyor ve böylece mevcut uygulama yapısının büyük bölümünü koruyabiliyorduk.
Ancak Cloudflare üzerinde Next.js çalıştırmayı, Vercel üzerinde Next.js çalıştırmakla eşdeğer görmedik. Next.js en sıkı biçimde Vercel'in çalışma ortamı, dağıtım sistemi, önbellekleme davranışı ve platform özellikleriyle bütünleşiyor. Cloudflare'de ise bu varsayımları farklı bir çalışma ortamına uyarlamak için bir adaptör gerekiyor.
Bu iyi çalışabilir, ancak hedefimiz teknoloji yığınını basitleştirmekse yeni bir uyumluluk katmanı eklemek pek ideal görünmüyordu.
Araçlarla ilgili daha geniş bir mesele de vardı. Ön uçta geliştirdiğimiz diğer neredeyse her şey — masaüstü uygulamaları, tarayıcı uzantıları, SPA'ler ve diğer istemci tarafı projeler — zaten Vite kullanıyordu.
Next.js büyük ölçüde Turbopack'e yönelmişti ve Turbopack önemli ölçüde gelişti. Bu, performansla ilgili bir şikâyet değildi. Bizim için asıl fark ekosistemdi. Vite, daha geniş eklenti ekosistemi ve projeler arasında daha kolay yeniden kullanılabilen yapılandırmalarıyla ön uç kod tabanımızın büyük bölümünde zaten ortak temel hâline gelmişti.
Dolayısıyla Next.js'i Cloudflare üzerinde tutmak barındırma sorununun bir kısmını çözerdi, ancak hem geliştirme çatısı uyumsuzluğunu hem de ayrı bir derleme araçları ekosistemini sürdürürdü.
Bu yüzden geri çekilip her iş yükünün gerçekte neye ihtiyaç duyduğuna baktık.
Teknoloji Yığınını İş Yüklerine Göre Ayırdık
Her şeye uyan tek bir Next.js alternatifi aramayı bırakınca mimari çok daha basit hâle geldi.
Pazarlama sitelerimiz, herkese açık ve yerelleştirilmiş sayfalara, meta verilere, kanonik URL'lere, site haritalarına ve arama motoru trafiğine sahip oldukları için SSR'ye ihtiyaç duyuyordu.
Diğer web uygulamalarımızın çoğunun SSR'ye ihtiyacı yoktu; bunlar TanStack Router kullanan Vite uygulamaları olabilirdi.
API'lerimizin ise bir React geliştirme çatısına hiç ihtiyacı yoktu. Standart bir Node.js çalışma ortamı onlar için daha uygundu.
Son yapı şöyleydi:
Web uygulamaları
Vite + TanStack Router
│
└── Cloudflare Workers
Pazarlama siteleri
TanStack Start + SSR
│
└── Cloudflare Workers
API'ler
Hono + tRPC
│
└── Railway / Node.js konteynerleri
Kural basitleşti: Gerçek değer sağladığı yerde SSR kullan, sağlamadığı yerde sıradan bir SPA kullan ve arka uç servislerini bir arka uç çalışma ortamında çalıştır.
Web Uygulamalarının Çoğu SPA'e Dönüştü
SPA geçişleri işin en kolay kısmıydı.
WebCatalog web uygulamasının geçişi özellikle hızlı oldu: Vite + TanStack Router ile yeni uygulamanın iskeletini oluşturduk, arayüzü taşıdık, dağıtımı Cloudflare Workers'a geçirdik ve eski Next.js sürümünü aynı sabah kaldırdık.
Aynı yöntemi Lexibird web uygulaması, hesap ayarları, geliştirici konsolumuz, kimlik doğrulama ve yönetim uygulamaları için de tekrarladık. İlk SPA iskeletini oluşturmamızdan son Next.js uygulamasını silmemize kadar yaklaşık 19 gün geçti.
Bu uygulamalarda Cloudflare Workers'ı bilerek basit bir şekilde kullanıyoruz. Vite statik dosyaları derliyor, Cloudflare bunları sunuyor ve uygulama rotaları gerektiğinde index.html dosyasına yönleniyor. Sunucu tarafında işlenmesi gereken bir şey olmadığından SSR çalışma ortamı da yok.
Daha zor olan, zaman içinde bu uygulamaların çevresinde birikmiş davranışları korumaktı. Bazı kimlik doğrulama mantıklarının Next.js sunucu rotalarından API'ye taşınması gerekti. WebCatalog masaüstü uygulamasının eski sürümleri de çalışır durumda tutmamız gereken eski uç noktalara bağımlıydı.
React arayüzünü taşımak kolaydı.
Mevcut arayüz sözleşmelerini korumak daha zordu.
Astro'yu Denedik ve Beş Gün Sonra Sildik
Pazarlama siteleri daha zordu.
İlk tercihimiz Astro oldu. webcatalog.io ve lexibird.com herkese açık, içerik ağırlıklı siteler olduğu ve Astro Cloudflare ile iyi bütünleştiği için doğal bir seçim gibi görünüyordu.
Her iki siteyi de taşımaya başladık; beş gün sonra durduk.
Tek bir büyük sorun yoktu. Bunun yerine küçük uyumsuzluklar birikiyordu. Derleme ortamımızda özellikle üretim veritabanı kimlik bilgilerini bulundurmamamıza rağmen bazı rotaların ön işleme sırasında veritabanına erişmesi gerekiyordu. React adacıkları, paylaşılan uygulama durumunu yönetmeyi daha az doğal hâle getiriyordu. Ayrıca önceden işlenen rotalarla çalışma zamanında işlenen rotalar arasındaki farklardan ve depomuzdaki araçlarla ilgili bazı pürüzlerden kaynaklanan sorunlarla karşılaştık.
Bu sorunların hiçbiri çözümsüz değildi. Devam etmeyi tehlikeli kılan da tam olarak buydu: Haftalarca bir sorunu çözüp ardından diğeriyle uğraşabilirdik.
Bunun yerine uygulamayı sildik ve baştan başladık.
Yapay zekâ ajanları bu kararın maliyet hesabını değiştirdi. Mekanik taşıma işinin büyük bir bölümü mühendislerin haftalarını almamıştı. Böylece boşa giden yatırım daha küçüktü ve başka bir mimariyi tercih ettiğimizi kabul etmek kolaylaştı.
TanStack Start Daha Uygundu
Pazarlama sitelerinin geçişine bu kez TanStack Start kullanarak, orijinal Next.js kodundan yeniden başladık.
SPA uygulamalarında zaten TanStack Router kullandığımız için çok daha doğal bir uyum sağladı: Rotalama, yükleyiciler, arama parametreleri ve gezinme benzer kavramlara dayanıyordu. Kod sıradan React ve TypeScript olarak kaldı; derleme sistemi ise Vite'tı.
lexibird.com'u bir günde TanStack Start'a taşıdık. Ardından webcatalog.io geldi.
TanStack Start'ın avantajı bütün sorunları sihirli biçimde çözmesi değildi. Teknoloji yığınımızın geri kalanının zaten yöneldiği yere uymasıydı.
Tek depolu bir yapıda bu önemli. Ortak derleme araçları; daha fazla yeniden kullanılabilir eklenti ve yapılandırma, hata ayıklarken daha az özel durum, geliştiriciler için daha az bağlam değiştirme ve kodlama ajanlarının öğrenmesi gereken daha az projeye özgü kural anlamına geliyor.
Cloudflare, Trafiğimiz İçin Çok Daha Ucuzdu
Faturamızın düşmesinin tek nedeni mimari değildi. Cloudflare'in fiyatlandırması, özellikle bant genişliği konusunda, önemli bir etkendi.
Cloudflare Workers Paid şu anda ağırlıklı olarak istek ve CPU kullanımına göre ücret alıyor ve Workers için veri aktarımı veya bant genişliği ücreti eklemiyor. (developers.cloudflare.com) Bu, herkese açık web siteleri için çok önemli: Bir istek çok az CPU kullanırken yine de HTML, JavaScript, görsel, yazı tipi ve başka dosyalar aktarabilir.
Vercel'in fiyatlandırma modeli ise Fast Data Transfer ve Fast Origin Transfer dâhil, ağla ilgili kullanım kategorileri ve kotalar da içeriyor. (vercel.com) Trafik profilimiz için Cloudflare'in maliyet yapısı çok daha avantajlıydı.
Tasarruf yalnızca sağlayıcı değiştirmekten kaynaklanmadı. Birçok uygulamayı statik Vite derlemelerine taşıdık, gereksiz SSR kullanımını azalttık, önbelleklemeyi daha açık biçimde tanımladık ve API iş yüklerini kendilerine daha uygun bir çalışma ortamına taşıdık. Ancak gözlemlediğimiz yaklaşık %80'lik azalmanın başlıca nedenlerinden biri, özellikle bant genişliği açısından Cloudflare'in fiyatlandırmasıydı.
Bu oran bizim iş yükümüze özgü. Vercel'den Cloudflare'e geçen her uygulamanın %80 tasarruf edeceğini iddia etmiyoruz.
API'ler Railway'e Taşındı
API'ler ayrı bir konuydu.
Next.js projeleri olmalarına rağmen zaten büyük ölçüde Next.js'ten bağımsızlardı. WebCatalog API'si yaklaşık 34.000 satır koddan oluşuyordu, fakat yalnızca yedi dosya next/server modülünü içe aktarıyordu. tRPC zaten Fetch adaptörünü kullanıyordu ve Inngest, Hono'yu destekliyordu.
Next.js HTTP katmanını Hono ile değiştirdik. Bu kısım şaşırtıcı derecede küçük bir değişiklikti.
Daha zor soru, API'leri nerede çalıştıracağımızdı. API'ler Node.js ve sharp gibi yerel bağımlılıklar kullandığından sıradan Workers uygun değildi.
Başta Cloudflare Containers'ı denedik. Bu sayede Vercel'den hızla çıkabildik. Ancak sistemi üretim ortamında çalıştırdıktan sonra, işletim modelinin o aşamada istediğimizden daha fazla elle kapasite ayarlaması gerektirdiğini gördük.
Bu yüzden API'leri bir kez daha taşıdık.
Bugün API'ler Railway üzerinde, sıradan ve uzun süre çalışan Node.js konteyner servisleri olarak çalışıyor. CI (sürekli entegrasyon) Docker imajlarını oluşturup kayıt sistemimize gönderiyor; Railway ise yatay otomatik ölçeklendirmeyi yönetiyor.
Her şeyin uç noktada çalışması gerekmiyor.
Vercel'den Ayrılmak Daha Fazla Sorumluluk Üstlenmek Demekti
Daha düşük maliyetin bir karşılığı vardı.
Vercel ve Next.js birçok altyapı davranışını daha üst düzeyde yönetiyordu. TanStack Start ve Workers ile bunun yerine açıkça tanımlanmış HTTP önbelleklemesine yöneldik. Bir sayfa işleniyor, önbellek başlıklarını döndürüyoruz ve Cloudflare yanıtı önbelleğe alıyor. Tarayıcı ve uç noktadaki önbelleklerin, uç noktada eski içeriği sunarken arka planda yeniden doğrulama davranışı dâhil, farklı politikaları olabiliyor.
Bu kararların açık hâle gelmesini sevdik; ancak altyapıyı açıkça yönetince hataların sorumluluğu da size ait oluyor.
Birkaç hata yaptık. Üretim ortamındaki bir önbellek kuralı yanlışlıkla ziyaretçiye özgü TanStack sunucu fonksiyonu yanıtlarıyla eşleşti. Başka bir önbellek yapılandırması da SPA'in geri dönüş davranışıyla kötü biçimde etkileşti. Bu hatalar, geçişin doğruluğunun yalnızca kod deposuna bakılarak kanıtlanamayacağını hatırlattı. Üretim altyapısı da sistemin bir parçası.
Yapay Zekâ Ajanları Geçiş Yöntemimizi Değiştirdi
Uygulama çalışmalarının çoğunu başta Claude Fable 5 ve Claude Opus 5 olmak üzere kodlama ajanları gerçekleştirdi.
Geliştirme çatısı geçişleri ajanlara özellikle uygun, çünkü işin büyük bölümünde başvurulabilecek mevcut bir örnek var: Bu rotayı taşı, şu URL'yi koru, bu geliştirme çatısı API'sini değiştir, aynı meta verileri tut, tür denetimini çalıştır, hataları düzelt ve sonucu eski uygulamayla karşılaştır.
webcatalog.io için çalışmayı temel yapı, ürün sayfaları, katalog sayfaları, arama, blog, fiyatlandırma, yönlendirmeler, site haritaları ve yeni sisteme geçiş gibi aşamalara bölen bir geçiş takip listesi tuttuk. Bir ajandan “webcatalog.io'yu TanStack Start'a taşımasını” istemek yerine, ona açıkça belirtilmiş ve korunması gereken koşulları içeren, sınırları belli görevler verdik.
Mevcut uygulama şartname hâline geldi. Ajanın görevi ürünü yeniden tasarlamak değil, davranışını yeni mimariyle yeniden üretmekti.
Bu, insanların emeğini kodu elle dönüştürmekten şu tür sorulara kaydırdı: Bu sayfa gerçekten SSR kullanmalı mı? Hangi davranış kasıtlı? Neler herkes için ortak biçimde önbelleğe alınabilir? Hangi URL'ler birebir aynı kalmalı? Kimlik doğrulama nerede yapılmalı? Bir yaklaşımı çalıştırmaya uğraşmayı ne zaman bırakmalıyız?
Yine de çıktıları gözden geçirdik, derlemeleri ve tür denetimlerini çalıştırdık; kimlik doğrulama, SEO (arama motoru optimizasyonu), yönlendirmeler ve önbellekleme gibi daha yüksek riskli alanları elle doğruladık.
Önemli değişiklik, yapay zekânın bizim için kod yazması değildi. Deneme yapmayı daha ucuz hâle getirmesiydi.
Astro'yu deneyip beş gün sonra silme kararını vermek çok daha kolaylaştı. API'leri bir kez taşıdıktan sonra başka bir platformun daha uygun olduğuna karar vermek daha az zahmetliydi. Mekanik işlerin maliyeti düştüğü için, mimari yanlış çıktığında sırf ona çok emek harcadık diye devam etmek yerine yön değiştirebildik.
Ajanlar uygulama emeğini daha kolay erişilebilir hâle getirdi.
Bu da mimariyi, kısıtları, incelemeyi ve doğrulamayı daha önemli kıldı.
%80, Yaklaşık %90'a Çıktı
Geçişten sonra web altyapısı maliyetimiz yaklaşık %80 daha düşüktü.
Ardından hangi isteklerin uygulamalara ulaştığına daha fazla dikkat etmeye başladık.
Herkese açık internetteki trafiğin kayda değer bir bölümü otomatik sistemlerden geliyor: arama motorları, yapay zekâ tarayıcıları, ajanlar, veri kazıyıcılar, güvenlik tarayıcıları ve daha az dostane botlar. Bu trafiğin bir kısmı yararlı, bir kısmı değil.
Uygulamalarımız doğrudan Cloudflare'in arkasında olduğundan, zararlı otomatik trafiğin uygulamada işlem veya veritabanı işi başlatmadan önce uç noktada reddedilmesi için güvenlik kurallarımızı sıkılaştırdık.
Bunun ardından eski düzene kıyasla toplam tasarrufumuz yaklaşık %90'a ulaştı.
Son azalmanın ardında birkaç etkenin birleşimi vardı: Cloudflare'in özellikle bant genişliği açısından daha düşük fiyatları; sunucu tarafında daha az işlem; API'lerimiz için daha uygun bir çalışma ortamı; daha açık biçimde tanımlanmış önbellekleme; ve uygulamalara ulaşan gereksiz istek sayısının azalması.
Geldiğimiz Nokta
Kod depomuzda artık hiçbir Next.js uygulaması yok. Web uygulamalarımızın çoğu artık Cloudflare Workers üzerinde Vite + TanStack Router ile geliştirilmiş SPA'ler. webcatalog.io ve lexibird.com, SSR'den gerçekten yararlandıkları için Cloudflare Workers üzerinde TanStack Start kullanıyor. API'lerimiz Railway üzerinde Hono + tRPC kullanıyor ve sıradan Node.js konteynerleri olarak çalışıyor. Ön uç projelerimizin neredeyse tamamı artık Vite ekosisteminde.
Altyapı maliyetimiz yaklaşık %80 düştü. Cloudflare'in trafiğimiz için, özellikle bant genişliği açısından, çok daha avantajlı olan maliyet yapısı buna büyük katkı sağladı. Zararlı otomatik trafiği uç noktada filtrelemek toplam tasarrufu yaklaşık %90'a taşıdı.
Ama bizim için en önemli sonuç mimariyle ilgili. Pazarlama siteleri SSR kullanıyor, SPA olabilecek diğer her şey SPA olarak çalışıyor ve gerçek sunucular daha basit bir çözüm sunduğunda API'ler gerçek sunucularda çalışıyor.
İşe Vercel'i daha ucuza kullanmaya çalışarak başladık.
Sonunda, parasını ödediğimiz mimarinin büyük bölümüne ihtiyacımız olmadığını fark ettik.