Kako nam je prelazak s Vercela na Cloudflare Workers i Railway smanjio troškove web-infrastrukture za 80 %

Migrirali smo naš web stack s Vercela na Cloudflare Workers i Railway te zamijenili Next.js kombinacijom TanStack Routera, TanStack Starta i Hona, ovisno o stvarnim potrebama svakog radnog opterećenja. Time su troškovi infrastrukture smanjeni za otprilike 80 %, odnosno za oko 90 % nakon filtriranja zlonamjernog automatiziranog prometa na rubu mreže. Većinu posla oko migracije obavili su AI agenti za programiranje, dok su se inženjeri usredotočili na arhitekturu, ograničenja, pregled i provjeru u produkciji.

23. rujna 2026.

Quang Lam · Founder & CEO

Kako nam je prelazak s Vercela na Cloudflare Workers i Railway smanjio troškove web-infrastrukture za 80 %

Godinama je Vercel bio zadano mjesto na koje smo u WebCatalogu postavljali gotovo sve što smo imali na webu. Većina tih projekata koristila je Next.js, pa je ta kombinacija bila prirodna. Naše marketinške stranice, sučelja proizvoda, postavke računa, konzola za razvojne programere, autentifikacija, administratorski alati i API-ji završili su na otprilike istom tehnološkom sklopu.

To je dugo dobro funkcioniralo. Vercel je pojednostavnio postavljanje aplikacija, Next.js nam je pružao produktivan okvir za frontend i backend, a o infrastrukturi na kojoj su se temeljili rijetko smo morali razmišljati.

S vremenom ta praktičnost više nije odgovarala potrebama naših proizvoda.

Našim marketinškim stranicama i dalje je koristio SSR (prikazivanje na poslužitelju), ali većini naših ostalih web-aplikacija nije. One su mogle biti obične SPA aplikacije (aplikacije s jednom stranicom). Naši API-ji trebali su uobičajeno Node.js okruženje s izvornim ovisnostima i dugotrajnim procesima. Gotovo sve ostalo u našem frontend sklopu već je koristilo Vite. Istodobno je troškove infrastrukture bilo sve teže zanemarivati, osobito kako je rastao javni i automatizirani promet.

Isprva smo pokušali optimizirati ono što smo već imali. Razmatrali smo zadržavanje Next.js-a i njegovo premještanje na Cloudflare Workers putem adaptera. Isprobali smo Astro za marketinške stranice. Nakratko smo svoje API-je postavili na Cloudflare Containers.

Na kraju smo došli do jednostavnijeg rješenja: većina naših web-aplikacija sada koristi Vite + TanStack Router na Cloudflare Workersima, naše marketinške stranice koriste TanStack Start sa SSR-om na Cloudflare Workersima, a naši API-ji koriste Hono + tRPC na Railwayu, kao dugotrajni Node.js kontejneri.

Migracija je smanjila naše troškove web-infrastrukture za otprilike 80 %. Nakon što smo dodatno postrožili sigurnosna pravila na Cloudflareu i na rubnoj mreži blokirali više neprijateljskog automatiziranog prometa, ukupna ušteda porasla je na oko 90 %.

Veći dio provedbe migracije također su obavili AI agenti za programiranje, prvenstveno Claude Fable 5 i Claude Opus 5, dok su inženjeri odlučivali o arhitekturi, definirali ograničenja, pregledavali promjene i provjeravali rezultat.

Nismo počeli odlukom da napustimo Vercel

Prvi nam je instinkt bio optimizirati postojeći sustav.

webcatalog.io bio je najočitije polazište jer prima mnogo javnog prometa, a većina njegovih stranica mijenja se razmjerno rijetko. Otkrili smo da se prevelik dio web-mjesta i dalje dinamički prikazuje, pa smo ispravili nenamjerno dinamičko prikazivanje, dodali ISR (inkrementalnu statičku regeneraciju) na rute s mnogo prometa, omogućili predmemoriranje većeg broja stranica i optimizirali zahtjevnu obradu mapa web-mjesta.

Taj je rad pomogao, ali je i jasnije pokazao temeljni problem. Sve smo više vremena trošili na otkrivanje zašto je razmjerno statičan sadržaj dinamičan, koje je ponašanje okvira to uzrokovalo i koji mehanizam okvira trebamo uvesti da bismo ga ponovno mogli predmemorirati.

Istodobno su mnoge naše druge aplikacije imale suprotan problem. Postavke računa, konzola za razvojne programere, administratorske aplikacije i većina sučelja proizvoda uopće nisu trebali prikazivanje na poslužitelju. Bile su to aplikacije u pregledniku koje komuniciraju s API-jima.

Tada pitanje više nije bilo „Kako da smanjimo račun za Vercel?”, nego „Što bismo izgradili da ove aplikacije već nisu izrađene u Next.js-u?”

Razmatrali smo Next.js na Cloudflareu

Najmanje disruptivna mogućnost bila je zadržati Next.js i premjestiti ga s Vercela na Cloudflare Workers.

Ozbiljno smo to razmatrali jer se Next.js može pokretati na Cloudflareu putem adapterskih slojeva, što bi nam omogućilo da zadržimo velik dio postojeće strukture aplikacija.

No Next.js na Cloudflareu nismo smatrali jednakovrijednim Next.js-u na Vercelu. Next.js je najtješnje povezan s Vercelovim izvršnim okruženjem, sustavom za postavljanje aplikacija, načinom predmemoriranja i značajkama platforme. Na Cloudflareu adapter mora prilagoditi te pretpostavke drukčijem izvršnom okruženju.

To može dobro funkcionirati, ali ako nam je cilj bio pojednostaviti tehnološki sklop, dodavanje još jednog sloja kompatibilnosti nije nam se činilo idealnim.

Postojalo je i šire pitanje alata. Gotovo sve ostalo što smo razvijali na frontendu već je koristilo Vite: desktop aplikacije, proširenja preglednika, SPA aplikacije i druge klijentske projekte.

Next.js se snažno usmjerio prema Turbopacku, koji se znatno poboljšao. Nije nam smetala njegova izvedba. Za nas je veća razlika bila u ekosustavu. Vite je već bio zajednički temelj većeg dijela našeg frontend koda, sa širim ekosustavom dodataka i konfiguracijom koja se lakše ponovno koristi u različitim projektima.

Zadržavanje Next.js-a na Cloudflareu stoga bi riješilo dio problema s hostingom, ali bi očuvalo i neusklađenost okvira i zaseban ekosustav alata za izgradnju.

Zato smo napravili korak unatrag i razmotrili što je svakom dijelu sustava zapravo potrebno.

Razdvojili smo tehnološki sklop prema namjeni

Kad smo prestali tražiti jednu univerzalnu zamjenu za Next.js, arhitektura je postala mnogo jednostavnija.

Našim marketinškim stranicama trebao je SSR jer imaju javne, lokalizirane stranice, metapodatke, kanonske URL-ove i mape web-mjesta te primaju promet iz tražilica.

Većina naših drugih web-aplikacija nije trebala SSR i mogla je jednostavno biti aplikacija izrađena u Viteu uz TanStack Router.

Našim API-jima React okvir uopće nije trebao; više im je odgovaralo uobičajeno Node.js izvršno okruženje.

Konačna podjela izgledala je ovako:

Web-aplikacije
Vite + TanStack Router
        │
        └── Cloudflare Workers

Marketinške stranice
TanStack Start + SSR
        │
        └── Cloudflare Workers

API-ji
Hono + tRPC
        │
        └── Railway / Node.js kontejneri

Pravilo je postalo jednostavno: koristite SSR ondje gdje donosi stvarnu vrijednost, običnu SPA aplikaciju ondje gdje je ne donosi, a pozadinske servise pokrećite u okruženju namijenjenom za njih.

Većina web-aplikacija postala je SPA

Migracije na SPA bile su najlakši dio.

Web-aplikaciju WebCatalog premjestili smo osobito brzo: pripremili smo početnu strukturu zamjene s Viteom i TanStack Routerom, prenijeli sučelje, prebacili postavljanje na Cloudflare Workers i istoga jutra uklonili staru verziju u Next.js-u.

Isti smo postupak ponovili za web-aplikaciju Lexibird, postavke računa, konzolu za razvojne programere, autentifikaciju i administratorske aplikacije. Od prve početne strukture SPA aplikacije do brisanja posljednje aplikacije u Next.js-u prošlo je oko 19 dana.

U tim je aplikacijama uloga Cloudflare Workersa namjerno jednostavna. Vite izrađuje statičke datoteke, Cloudflare ih poslužuje, a rute aplikacije prema potrebi vraćaju index.html. Nema SSR izvršnog okruženja jer ništa ne zahtijeva prikazivanje na poslužitelju.

Teži dio bio je očuvati ponašanje koje se s vremenom nakupilo oko tih aplikacija. Dio autentifikacijske logike morali smo premjestiti iz poslužiteljskih ruta Next.js-a u API, a starije verzije desktop aplikacije WebCatalog još su ovisile o starim pristupnim točkama, koje smo morali zadržati funkcionalnima.

Premjestiti React sučelje bilo je lako.

Očuvati postojeće ugovore bilo je teže.

Isprobali smo Astro i izbrisali ga pet dana poslije

Marketinške stranice bile su teži slučaj.

Naš prvi izbor bio je Astro, koji se činio prirodnim rješenjem za webcatalog.io i lexibird.com jer su oba javna web-mjesta s mnogo sadržaja, a Astro se dobro integrira s Cloudflareom.

Počeli smo prenositi oba web-mjesta, a pet dana poslije stali smo.

Nije postojao jedan presudan nedostatak. Umjesto toga gomilale su se manje neusklađenosti. Nekim je rutama tijekom pretprikazivanja trebao pristup bazi podataka, dok naše okruženje za izgradnju namjerno nije imalo vjerodajnice za produkcijsku bazu. React otoci otežavali su prirodno dijeljenje stanja aplikacije. Naišli smo i na razlike između unaprijed prikazanih ruta i ruta koje se prikazuju tijekom izvršavanja te na određene poteškoće s alatima u našem repozitoriju.

Nijedan od tih problema nije bio nerješiv. Upravo je zato nastavak bio opasan. Lako smo mogli potrošiti još nekoliko tjedana rješavajući jednu stvar za drugom.

Umjesto toga izbrisali smo implementaciju i počeli ispočetka.

AI agenti promijenili su računicu te odluke. Velik dio mehaničkog prijenosa nije nam oduzeo tjedne inženjerskog rada, pa su već nastali troškovi bili manji i bilo je lakše priznati da nam više odgovara druga arhitektura.

TanStack Start bolje se uklopio

Ponovno smo započeli migraciju marketinških stranica iz izvornog koda u Next.js-u, ovaj put koristeći TanStack Start.

Uklopio se mnogo prirodnije jer smo u SPA aplikacijama već koristili TanStack Router, pa su se usmjeravanje, učitavači, parametri pretraživanja i navigacija temeljili na sličnim konceptima. Kod je ostao uobičajeni React i TypeScript, a sustav za izgradnju bio je Vite.

lexibird.com prenijeli smo na TanStack Start u jednom danu. Zatim je slijedio webcatalog.io.

Prednost nije bila u tome što je TanStack Start čarobno riješio svaki problem. Prednost je bila u tome što se uklapao u smjer u kojem se ostatak našeg tehnološkog sklopa već kretao.

U monorepozitoriju to je važno. Zajednički alati za izgradnju znače više dodataka i konfiguracije koje se mogu ponovno koristiti, manje posebnih slučajeva pri otklanjanju pogrešaka, manje prebacivanja između različitih konteksta za razvojne programere i manje konvencija specifičnih za pojedini projekt koje agenti za programiranje moraju otkriti.

Cloudflare je za naš promet bio mnogo jeftiniji

Arhitektura je bila samo dio razloga za pad naših troškova. Cloudflareove cijene bile su važan čimbenik, osobito cijene prijenosa podataka.

Plaćeni plan Cloudflare Workers trenutačno se naplaćuje prvenstveno prema zahtjevima i potrošnji procesorskog vremena te ne naplaćuje dodatno prijenos podataka ni propusnost za Worker usluge. (developers.cloudflare.com) To je vrlo važno za javna web-mjesta jer zahtjev može potrošiti vrlo malo procesorskog vremena, a ipak prenijeti HTML, JavaScript, slike, fontove i druge datoteke.

Vercelov model naplate također uključuje kategorije potrošnje i uključene količine povezane s mrežnim prometom, među njima Fast Data Transfer i Fast Origin Transfer. (vercel.com) Za naš profil prometa Cloudflare je bio znatno povoljniji.

Ušteda nije proizašla samo iz promjene pružatelja usluge. Mnoge smo aplikacije pretvorili u statičke inačice izgrađene Viteom, smanjili nepotreban SSR, jasnije definirali predmemoriranje i premjestili API-je u izvršno okruženje koje im bolje odgovara. No Cloudflareove cijene, osobito u pogledu prijenosa podataka, znatno su pridonijele smanjenju od otprilike 80 % koje smo zabilježili.

Ta je brojka specifična za naše potrebe. Ne tvrdimo da će svaka aplikacija premještanjem s Vercela na Cloudflare uštedjeti 80 %.

API-ji su završili na Railwayu

API-ji su bili zaseban problem.

Iako su bili projekti u Next.js-u, već su uglavnom bili neovisni o njemu. WebCatalogov API imao je otprilike 34 000 redaka, ali samo je sedam datoteka uvozilo next/server. tRPC je već koristio svoj Fetch adapter, a Inngest je podržavao Hono.

Zamijenili smo Next.js sloj za HTTP s Honom. Taj je dio bio iznenađujuće malen.

Teže je bilo odlučiti gdje ga pokretati. Sami Workersi nisu bili dobro rješenje jer API-ji koriste Node.js i izvorne ovisnosti poput sharp.

Isprva smo isprobali Cloudflare Containers, što nam je omogućilo brz odlazak s Vercela. No nakon što smo to rješenje pokrenuli u produkciji, ustanovili smo da njegov operativni model zahtijeva više ručnog podešavanja kapaciteta nego što smo tada željeli.

Zato smo API-je ponovno premjestili.

Danas se pokreću na Railwayu kao uobičajeni dugotrajni Node.js servisi u kontejnerima. CI (kontinuirana integracija) izrađuje Docker slike i šalje ih u naš registar, a Railway upravlja horizontalnim automatskim skaliranjem.

Ne mora se sve pokretati na rubnoj mreži.

Odlazak s Vercela značio je preuzimanje više odgovornosti

Niži trošak imao je svoju cijenu.

Vercel i Next.js rješavali su mnoge infrastrukturne funkcije na višoj razini. Uz TanStack Start i Workerse prešli smo na izričitije HTTP predmemoriranje. Stranica se prikaže, mi vratimo zaglavlja za predmemoriranje, a Cloudflare pohrani odgovor u predmemoriju. Predmemoriranje u pregledniku i na rubnoj mreži može imati različita pravila, uključujući posluživanje zastarjelog sadržaja uz ponovnu provjeru u pozadini na rubnoj mreži.

Svidjelo nam se što su te odluke postale izričite, ali izričito upravljanje infrastrukturom znači i da su pogreške vaše.

Napravili smo ih nekoliko. Jedno produkcijsko pravilo predmemoriranja slučajno je obuhvatilo odgovore TanStackovih poslužiteljskih funkcija specifične za pojedinog posjetitelja, a druga je konfiguracija predmemorije loše djelovala u kombinaciji s rezervnim usmjeravanjem SPA aplikacije. Te su nas pogreške korisno podsjetile da se ispravnost migracije ne može u cijelosti dokazati samo pregledom repozitorija. I produkcijska infrastruktura dio je sustava.

AI agenti promijenili su način na koji smo proveli migraciju

Većinu implementacijskog posla obavili su agenti za programiranje, prvenstveno Claude Fable 5 i Claude Opus 5.

Migracije između okvira osobito su pogodne za agente jer za velik dio posla postoji jasna postojeća referenca. Premjesti ovu rutu, sačuvaj ovaj URL, zamijeni ovaj API okvira, zadrži iste metapodatke, pokreni provjeru tipova, ispravi pogreške i usporedi rezultat sa starom implementacijom.

Za webcatalog.io vodili smo evidenciju migracije koja je posao dijelila na faze poput temelja, stranica proizvoda, stranica kataloga, pretraživanja, bloga, cijena, preusmjeravanja, mapa web-mjesta i konačnog prebacivanja. Umjesto da agentu kažemo „Migriraj webcatalog.io na TanStack Start”, zadavali smo mu jasno ograničene zadatke s izričitim zahtjevima koji moraju ostati ispunjeni.

Postojeća aplikacija postala je specifikacija. Zadatak agenta bio je reproducirati ponašanje u novoj arhitekturi, a ne iznova osmišljavati proizvod.

Tako se ljudski rad preusmjerio s ručnog prevođenja koda na pitanja poput: Treba li ova stranica doista koristiti SSR? Koje je ponašanje namjerno? Što se smije globalno predmemorirati? Koji URL-ovi moraju ostati potpuno isti? Gdje se treba odvijati autentifikacija? Kada trebamo prestati pokušavati osposobiti neki pristup?

I dalje smo pregledavali rezultate, pokretali izgradnju i provjere tipova te ručno provjeravali rizičnija područja poput autentifikacije, SEO-a (optimizacije za tražilice), preusmjeravanja i predmemoriranja.

Važna promjena nije bila to što je AI pisao kod umjesto nas. Bila je u tome što je AI pojeftinio eksperimentiranje.

Isprobavanje Astra i njegovo brisanje nakon pet dana postalo je mnogo lakše opravdati. Bilo je manje bolno jednom premjestiti API-je pa potom odlučiti da nam druga platforma bolje odgovara. Mehanički dio posla bio je jeftiniji, pa smo mogli promijeniti smjer kad se arhitektura pokazala pogrešnom, umjesto da nastavimo samo zato što smo u nju već previše uložili.

Uz agente implementacija više nije bila toliko ograničavajući resurs.

Zato su arhitektura, ograničenja, pregled i provjera postali važniji.

Ušteda od 80 % porasla je na otprilike 90 %

Nakon migracije trošak naše web-infrastrukture bio je otprilike 80 % niži.

Zatim smo počeli više pozornosti posvećivati tome koji zahtjevi uopće dolaze do aplikacija.

Značajan dio prometa na javnom internetu automatiziran je: tražilice, AI pretraživači, agenti, alati za prikupljanje podataka, skeneri i manje prijateljski botovi. Dio tog prometa koristan je, a dio nije.

Budući da su aplikacije bile izravno iza Cloudflarea, postrožili smo sigurnosna pravila kako bismo neprijateljski automatizirani promet mogli odbiti na rubnoj mreži prije nego što pokrene obradu u aplikaciji ili rad s bazom podataka.

Nakon toga naša je ukupna ušteda dosegla otprilike 90 % u usporedbi sa starim sustavom.

Konačno smanjenje proizašlo je iz zajedničkog djelovanja više čimbenika: nižih Cloudflareovih cijena, osobito za prijenos podataka; manje obrade na poslužitelju; prikladnijeg izvršnog okruženja za naše API-je; jasnije definiranog predmemoriranja; i manjeg broja nepotrebnih zahtjeva koji uopće stižu do aplikacija.

Gdje smo završili

U našem repozitoriju više nema nijedne aplikacije u Next.js-u. Većina naših web-aplikacija sada su SPA aplikacije izrađene uz Vite + TanStack Router na Cloudflare Workersima. webcatalog.io i lexibird.com koriste TanStack Start na Cloudflare Workersima jer tim web-mjestima SSR doista koristi. Naši API-ji koriste Hono + tRPC na Railwayu i pokreću se kao uobičajeni Node.js kontejneri. Gotovo svi naši frontend projekti sada su u ekosustavu Vitea.

Trošak naše infrastrukture pao je za otprilike 80 %, čemu je snažno pridonijela znatno povoljnija Cloudflareova cijena za naš promet, osobito prijenos podataka. Filtriranje neprijateljskog automatiziranog prometa na rubnoj mreži povećalo je ukupnu uštedu na oko 90 %.

No najvažniji nam je arhitekturni rezultat. Marketinške stranice dobivaju SSR, sve što može biti SPA jest SPA, a API-ji se pokreću na pravim poslužiteljima kada je to jednostavnije.

Počeli smo pokušajem da Vercel učinimo jeftinijim.

Završili smo spoznajom da nam veći dio arhitekture koju smo plaćali uopće nije potreban.