Miten siirtyminen Vercelistä Cloudflare Workersiin ja Railwayhin pienensi verkkoinfrastruktuurimme kustannuksia 80 prosenttia

Siirsimme verkkopalveluidemme teknologiapinon Vercelistä Cloudflare Workersiin ja Railwayhin. Korvasimme Next.js:n TanStack Routerin, TanStack Startin ja Honon yhdistelmällä sen mukaan, mitä kukin työkuorma todella tarvitsi. Infrastruktuurikustannukset pienenivät noin 80 %, ja kustannussäästö nousi noin 90 prosenttiin, kun haitallinen automatisoitu liikenne suodatettiin verkon reunalla. Suurimman osan siirtotyöstä tekivät tekoälypohjaiset koodausagentit, kun taas insinöörit keskittyivät arkkitehtuuriin, reunaehtoihin, katselmointiin ja toimivuuden varmistamiseen tuotantoympäristössä.

23. syyskuuta 2026

Quang Lam · Founder & CEO

Miten siirtyminen Vercelistä Cloudflare Workersiin ja Railwayhin pienensi verkkoinfrastruktuurimme kustannuksia 80 prosenttia

Vercel oli vuosien ajan WebCatalogin oletusalusta lähes kaikelle, mitä julkaisimme verkossa. Useimmat projektit käyttivät Next.js:ää, joten yhdistelmä oli luonteva. Markkinointisivustomme, tuotteiden käyttöliittymät, tiliasetukset, kehittäjäkonsoli, tunnistautuminen, ylläpitotyökalut ja rajapinnat päätyivät kaikki suunnilleen saman teknologiapinon varaan.

Ratkaisu toimi pitkään hyvin. Vercel teki julkaisuista yksinkertaisia, Next.js tarjosi tuottavan full stack -sovelluskehyksen, eikä meidän juuri tarvinnut ajatella kummankaan taustalla olevaa infrastruktuuria.

Lopulta tämä helppous ei enää vastannut tuotteidemme tarpeita.

Markkinointisivustomme hyötyivät edelleen SSR:stä (palvelinpuolen renderöinnistä), mutta useimmat muut verkkosovelluksemme eivät. Ne olisivat voineet olla tavallisia SPA-sovelluksia (yhden sivun sovelluksia). Rajapintamme tarvitsivat tavanomaisen Node.js-ympäristön, jossa voi käyttää natiiviriippuvuuksia ja pitkäkestoisia prosesseja. Lähes kaikki muu frontend-teknologiapinossamme käytti jo Viteä. Samalla infrastruktuurikustannuksia oli yhä vaikeampi sivuuttaa, etenkin julkisen ja automatisoidun liikenteen kasvaessa.

Yritimme ensin optimoida nykyistä ratkaisua. Harkitsimme Next.js:n säilyttämistä ja siirtämistä sovittimen avulla Cloudflare Workersiin. Kokeilimme Astroa markkinointisivustoilla. Siirsimme rajapintamme lyhyeksi aikaa Cloudflare Containersiin.

Lopulta päädyimme yksinkertaisempaan ratkaisuun: useimmat verkkosovelluksemme käyttävät nyt Viteä ja TanStack Routeria Cloudflare Workersissa, markkinointisivustomme käyttävät TanStack Startia ja SSR:ää Cloudflare Workersissa, ja rajapintamme käyttävät Honoa ja tRPC:tä Railwayssa pitkäkestoisina Node.js-kontteina.

Migraatio pienensi verkkoinfrastruktuurimme kustannuksia noin 80 %. Kun lisäksi tiukensimme Cloudflaren tietoturvasääntöjä ja estimme entistä enemmän haitallista automatisoitua liikennettä reunaverkossa, kokonaissäästöt nousivat noin 90 %:iin.

Suurimman osan migraation toteutuksesta tekivät myös tekoälypohjaiset koodausagentit, pääasiassa Claude Fable 5 ja Claude Opus 5. Insinöörit päättivät arkkitehtuurista, määrittelivät reunaehdot, tarkistivat muutokset ja varmistivat lopputuloksen.

Emme aloittaneet lähtemällä Vercelistä

Ensimmäinen ajatuksemme oli optimoida nykyinen ratkaisu.

webcatalog.io oli ilmeisin aloituskohde, koska se saa paljon julkista liikennettä, vaikka suurin osa sen sivuista muuttuu suhteellisen harvoin. Huomasimme, että liian suuri osa sivustosta renderöitiin edelleen dynaamisesti. Korjasimme tahattoman dynaamisen renderöinnin, lisäsimme vilkkaasti käytetyille reiteille ISR:n (Incremental Static Regeneration), teimme useammista sivuista välimuistiin tallennettavia ja optimoimme raskasta sivustokarttojen käsittelyä.

Työ auttoi, mutta teki myös perusongelman selvemmäksi. Käytimme yhä enemmän aikaa sen selvittämiseen, miksi suhteellisen staattinen sisältö oli dynaamista, mikä sovelluskehyksen toiminta sen aiheutti ja mitä sovelluskehyksen ominaisuutta tarvittiin, jotta sisältö voitaisiin jälleen tallentaa välimuistiin.

Monilla muilla sovelluksillamme oli samaan aikaan päinvastainen ongelma. Tiliasetukset, kehittäjäkonsoli, ylläpitosovellukset ja useimmat tuotteiden käyttöliittymät eivät tarvinneet palvelinpuolen renderöintiä lainkaan. Ne olivat selaimessa toimivia sovelluksia, jotka keskustelivat rajapintojen kanssa.

Siinä vaiheessa kysymys ei enää ollut ”Miten pienennämme Vercel-laskuamme?” vaan ”Mitä rakentaisimme, jos nämä sovellukset eivät jo olisi Next.js-sovelluksia?”

Harkitsimme Next.js:ää Cloudflaressa

Vähiten muutoksia vaativa vaihtoehto oli säilyttää Next.js ja siirtää se Vercelistä Cloudflare Workersiin.

Harkitsimme tätä vakavasti, koska Next.js:ää voi käyttää Cloudflaressa sovitinkerrosten avulla. Niiden ansiosta olisimme voineet säilyttää suuren osan sovellusten nykyisestä rakenteesta.

Emme kuitenkaan pitäneet Next.js:ää Cloudflaressa samanveroisena ratkaisuna kuin Next.js:ää Vercelissä. Next.js on tiiviimmin integroitu Vercelin suoritusympäristöön, julkaisujärjestelmään, välimuistin toimintaan ja alustan ominaisuuksiin. Cloudflaressa sovittimen on mukautettava nämä oletukset toiseen suoritusympäristöön.

Se voi toimia hyvin, mutta jos tavoitteenamme oli yksinkertaistaa teknologiapinoa, uuden yhteensopivuuskerroksen lisääminen ei tuntunut ihanteelliselta.

Myös työkalukokonaisuudessa oli laajempi ongelma. Lähes kaikki muut rakentamamme frontend-projektit käyttivät jo Viteä: työpöytäsovellukset, selainlaajennukset, SPA-sovellukset ja muut selainpuolen projektit.

Next.js oli siirtynyt vahvasti Turbopackin suuntaan, ja Turbopack on kehittynyt huomattavasti. Kyse ei ollut suorituskykyä koskevasta valituksesta. Meille suurempi ero oli ekosysteemissä. Vite oli jo yhteinen perusta suurimmalle osalle frontend-koodikantaamme, ja sillä oli laajempi lisäosaekosysteemi sekä enemmän projektien välillä uudelleenkäytettäviä määrityksiä.

Next.js:n säilyttäminen Cloudflaressa olisi siis ratkaissut osan palvelualustaongelmasta, mutta sovelluskehysten epäsuhta ja erillinen koontityökalujen ekosysteemi olisivat jääneet.

Otimme siksi askeleen taaksepäin ja tarkastelimme, mitä kukin kuormitus todella tarvitsi.

Jaoimme teknologiapinon käyttötarpeen mukaan

Kun lakkasimme etsimästä yhtä yleispätevää Next.js:n korvaajaa, arkkitehtuurista tuli paljon yksinkertaisempi.

Markkinointisivustomme tarvitsivat SSR:ää, koska niillä on julkisia, lokalisoituja sivuja, metatietoja, kanonisia URL-osoitteita, sivustokarttoja ja hakukoneliikennettä.

Useimmat muut verkkosovelluksemme eivät tarvinneet SSR:ää, vaan saattoivat olla yksinkertaisesti Vite-sovelluksia, joissa käytetään TanStack Routeria.

Rajapintamme eivät tarvinneet React-sovelluskehystä lainkaan, vaan niille sopi paremmin tavallinen Node.js-suoritusympäristö.

Lopullinen jako näytti tältä:

Verkkosovellukset
Vite + TanStack Router
        │
        └── Cloudflare Workers

Markkinointisivustot
TanStack Start + SSR
        │
        └── Cloudflare Workers

Rajapinnat
Hono + tRPC
        │
        └── Railway / Node.js-kontit

Periaatteesta tuli selkeä: käytä SSR:ää siellä, missä siitä on todellista hyötyä, tavallista SPA-sovellusta siellä, missä SSR:stä ei ole hyötyä, ja suorita taustapalvelut niille tarkoitetussa ympäristössä.

Useimmista verkkosovelluksista tuli SPA-sovelluksia

SPA-migraatiot olivat helpoin osa.

WebCatalogin verkkosovelluksen siirto eteni erityisen nopeasti: loimme rungon Viteen ja TanStack Routeriin perustuvalle korvaavalle sovellukselle, siirsimme käyttöliittymän, vaihdoimme julkaisualustaksi Cloudflare Workersin ja poistimme vanhan Next.js-version saman aamupäivän aikana.

Toistimme saman mallin Lexibirdin verkkosovelluksessa, tiliasetuksissa, kehittäjäkonsolissa, tunnistautumisessa ja ylläpitosovelluksissa. Ensimmäisen SPA-sovelluksen rungon luomisesta viimeisen Next.js-sovelluksen poistamiseen kului noin 19 päivää.

Näissä sovelluksissa Cloudflare Workersin rooli on tarkoituksella yksinkertainen. Vite koostaa staattiset resurssit, Cloudflare tarjoaa ne käyttäjille, ja sovellusreitit ohjautuvat tarvittaessa index.html-tiedostoon. SSR-suoritusympäristöä ei ole, koska mikään ei vaadi palvelinpuolen renderöintiä.

Vaikeampaa oli säilyttää toiminta, jota sovellusten ympärille oli kertynyt vuosien mittaan. Osa tunnistautumislogiikasta oli siirrettävä Next.js:n palvelinreiteiltä rajapintaan, ja WebCatalogin työpöytäsovelluksen vanhemmat versiot olivat edelleen riippuvaisia vanhoista päätepisteistä, joiden toiminta meidän oli turvattava.

React-käyttöliittymän siirtäminen oli helppoa.

Yhteensopivuuden säilyttäminen oli vaikeampaa.

Kokeilimme Astroa ja poistimme sen viiden päivän kuluttua

Markkinointisivustot olivat vaikeampia.

Ensimmäinen valintamme oli Astro, joka vaikutti luontevalta ratkaisulta webcatalog.io- ja lexibird.com-sivustoille. Molemmat ovat julkisia, sisältöpainotteisia sivustoja, ja Astro integroituu hyvin Cloudflareen.

Aloitimme molempien sivustojen siirtämisen, mutta lopetimme viisi päivää myöhemmin.

Mitään yksittäistä ratkaisevaa puutetta ei ollut. Pieniä yhteensopivuusongelmia kuitenkin kertyi. Osa reiteistä tarvitsi tietokantayhteyden esirenderöinnin aikana, vaikka koontiympäristössämme ei tarkoituksella ollut tuotantotietokannan tunnuksia. React-islandit tekivät yhteisen sovellustilan käsittelystä vähemmän luontevaa. Törmäsimme myös eroihin esirenderöityjen ja ajonaikaisesti renderöityjen reittien välillä sekä joihinkin työkaluihin liittyviin hankaluuksiin repositoriossamme.

Mikään näistä ongelmista ei ollut mahdoton ratkaista. Juuri siksi jatkaminen olisi ollut vaarallista. Olisimme helposti voineet käyttää vielä muutaman viikon ongelmien ratkomiseen yksi kerrallaan.

Sen sijaan poistimme toteutuksen ja aloitimme alusta.

Tekoälyagentit muuttivat tämän päätöksen kustannuslaskelmaa. Mekaaniseen siirtotyöhön ei ollut kulunut viikkoja insinöörien aikaa, joten uponneet kustannukset olivat pienemmät ja oli helpompi myöntää, että pidimme toisesta arkkitehtuurista enemmän.

TanStack Start sopi paremmin

Aloitimme markkinointisivustojen migraation uudelleen alkuperäisestä Next.js-koodista, tällä kertaa TanStack Startilla.

Se sopi kokonaisuuteen paljon luontevammin, koska käytimme jo TanStack Routeria SPA-sovelluksissa. Reititys, latausfunktiot, hakumääritysparametrit ja navigointi noudattivat siten samankaltaisia periaatteita. Koodi pysyi tavallisena Reactina ja TypeScriptinä, ja koontijärjestelmänä toimi Vite.

Siirsimme lexibird.comin TanStack Startiin päivässä. webcatalog.io seurasi perässä.

Etuna ei ollut se, että TanStack Start olisi ratkaissut kaikki ongelmat kuin taikaiskusta. Se sopi suuntaan, johon muu teknologiapinomme oli jo menossa.

Monorepossa sillä on merkitystä. Yhteiset koontityökalut tarkoittavat paremmin uudelleenkäytettäviä lisäosia ja määrityksiä, vähemmän erikoistapauksia virheenjäljityksessä, vähemmän kontekstin vaihtamista kehittäjille ja vähemmän projektikohtaisia käytäntöjä, jotka koodausagenttien on löydettävä.

Cloudflare oli liikenteellemme paljon halvempi

Arkkitehtuuri oli vain yksi syy laskumme pienenemiseen. Cloudflaren hinnoittelu oli merkittävä tekijä, etenkin tiedonsiirron osalta.

Cloudflare Workersin maksullinen palvelu veloittaa nykyisin ensisijaisesti pyyntöjen ja suorittimen käytön perusteella eikä lisää Workersille tiedonsiirto- tai kaistanleveysmaksuja. (developers.cloudflare.com) Tällä on suuri merkitys julkisille verkkosivustoille, koska pyyntö voi kuluttaa hyvin vähän suoritinaikaa mutta siirtää silti HTML:ää, JavaScriptiä, kuvia, fontteja ja muita resursseja.

Myös Vercelin hinnoittelumallissa on verkkoliikenteeseen liittyviä käyttöluokkia ja käyttökiintiöitä, kuten Fast Data Transfer ja Fast Origin Transfer. (vercel.com) Meidän liikenneprofiilillamme Cloudflare oli kustannuksiltaan huomattavasti edullisempi.

Säästöt eivät syntyneet pelkästään palveluntarjoajan vaihdosta. Siirsimme myös monia sovelluksia staattisiksi Vite-koonneiksi, vähensimme tarpeetonta SSR:ää, teimme välimuistituksesta selkeämmin määriteltyä ja siirsimme rajapintakuormat niille paremmin sopivaan suoritusympäristöön. Cloudflaren hinnoittelu, erityisesti tiedonsiirron osalta, vaikutti kuitenkin merkittävästi havaitsemaamme noin 80 prosentin vähennykseen.

Luku koskee meidän kuormitustamme. Emme väitä, että jokainen Vercelistä Cloudflareen siirtyvä sovellus säästäisi 80 %.

Rajapinnat päätyivät Railwayhin

Rajapinnat olivat erillinen ongelma.

Vaikka ne olivat Next.js-projekteja, ne olivat jo enimmäkseen riippumattomia Next.js:stä. WebCatalogin rajapinnassa oli noin 34 000 koodiriviä, mutta vain seitsemän tiedostoa toi next/server-moduulin. tRPC käytti jo Fetch-sovitintaan, ja Inngest tuki Honoa.

Korvasimme Next.js:n HTTP-kerroksen Honolla. Tämä osa oli yllättävän pieni.

Vaikeampi kysymys oli, missä rajapinnat suoritettaisiin. Tavalliset Workers-ympäristöt eivät sopineet hyvin, koska rajapinnat käyttävät Node.js:ää ja natiiviriippuvuuksia, kuten sharp-kirjastoa.

Kokeilimme ensin Cloudflare Containersia, jonka avulla pääsimme nopeasti pois Vercelistä. Kun ratkaisu oli ollut tuotannossa, huomasimme kuitenkin, että sen ylläpitomalli vaati enemmän manuaalista kapasiteetin säätämistä kuin tuolloin halusimme.

Niinpä siirsimme rajapinnat uudelleen.

Nykyään ne toimivat Railwayssa tavallisina pitkäkestoisina Node.js-konttipalveluina. CI (jatkuva integrointi) rakentaa Docker-imaget ja vie ne rekisteriimme, ja Railway hoitaa horisontaalisen automaattisen skaalauksen.

Kaiken ei tarvitse toimia reunaverkossa.

Vercelistä lähteminen lisäsi omaa vastuutamme

Pienemmillä kustannuksilla oli kääntöpuolensa.

Vercel ja Next.js olivat huolehtineet monista infrastruktuurin toimintatavoista korkeamman tason abstraktioina. TanStack Startin ja Workersin kanssa siirryimme sen sijaan tarkasti määriteltyyn HTTP-välimuistitukseen. Sivu renderöidään, palautamme välimuistiotsakkeet, ja Cloudflare tallentaa vastauksen välimuistiin. Selaimen ja reunaverkon välimuisteilla voi olla erilaiset käytännöt, mukaan lukien reunaverkon stale-while-revalidate-toiminta.

Pidimme siitä, että päätökset tulivat näkyviksi, mutta suoraan hallitsemasi infrastruktuurin virheet ovat myös omalla vastuullasi.

Teimme muutaman virheen. Yksi tuotannon välimuistisääntö osui vahingossa kävijäkohtaisiin TanStackin palvelinfunktioiden vastauksiin, ja toinen välimuistimääritys toimi huonosti yhteen SPA-sovelluksen varareitityksen kanssa. Nämä virheet muistuttivat hyödyllisesti siitä, ettei migraation oikeellisuutta voi todistaa kokonaan repositorion perusteella. Myös tuotantoinfrastruktuuri on osa järjestelmää.

Tekoälyagentit muuttivat tapaamme tehdä migraatioita

Suurimman osan toteutustyöstä tekivät koodausagentit, pääasiassa Claude Fable 5 ja Claude Opus 5.

Sovelluskehysmigraatiot sopivat agenteille poikkeuksellisen hyvin, koska suurelle osalle työstä on olemassa selkeä vertailukohta. Siirrä tämä reitti, säilytä tämä URL-osoite, korvaa tämä sovelluskehyksen rajapinta, pidä metatiedot ennallaan, suorita tyyppitarkistus, korjaa virheet ja vertaa lopputulosta vanhaan toteutukseen.

Pidimme webcatalog.io:ta varten migraation seurantaa, jossa työ jaettiin vaiheisiin, kuten perusta, tuotesivut, luettelosivut, haku, blogi, hinnoittelu, uudelleenohjaukset, sivustokartat ja käyttöönotto. Sen sijaan, että olisimme pyytäneet agenttia ”siirtämään webcatalog.io:n TanStack Startiin”, annoimme sille rajattuja tehtäviä ja selkeät ehdot, joiden oli säilyttävä voimassa.

Olemassa olevasta sovelluksesta tuli määrittely. Agentin tehtävänä oli toisintaa sen toiminta uudella arkkitehtuurilla, ei keksiä tuotetta uudelleen.

Näin ihmisten työ siirtyi koodin käsin kääntämisestä esimerkiksi tällaisiin kysymyksiin: Pitäisikö tämän sivun todella käyttää SSR:ää? Mikä toiminta on tarkoituksellista? Mitä voidaan tallentaa yhteiseen välimuistiin? Minkä URL-osoitteiden on pysyttävä täsmälleen samoina? Missä tunnistautumisen pitäisi tapahtua? Milloin jonkin lähestymistavan toimimaan saaminen kannattaa lopettaa?

Tarkistimme silti tuotokset, suoritimme koonnit ja tyyppitarkistukset sekä varmistimme käsin suuremman riskin osa-alueet, kuten tunnistautumisen, SEO:n (hakukoneoptimoinnin), uudelleenohjaukset ja välimuistituksen.

Olennainen muutos ei ollut se, että tekoäly kirjoitti koodia puolestamme. Se oli se, että tekoäly teki kokeilemisesta halvempaa.

Astron kokeileminen ja toteutuksen poistaminen viiden päivän kuluttua oli paljon helpompi perustella. Rajapintojen siirtäminen kerran ja sen jälkeen toisen alustan toteaminen paremmaksi vaihtoehdoksi oli vähemmän tuskallista. Mekaaninen työ oli halvempaa, joten pystyimme muuttamaan suuntaa, kun arkkitehtuuri oli väärä, sen sijaan että olisimme jatkaneet vain siksi, että olimme jo panostaneet siihen liikaa.

Agentit tekivät toteutustyöstä vähemmän niukan resurssin.

Se teki arkkitehtuurista, reunaehdoista, tarkistamisesta ja varmistamisesta entistä tärkeämpiä.

80 prosentista tuli noin 90 prosenttia

Migraation jälkeen verkkoinfrastruktuurimme kustannukset olivat noin 80 % pienemmät.

Sen jälkeen aloimme kiinnittää enemmän huomiota siihen, mitkä pyynnöt ylipäätään pääsivät sovelluksiin asti.

Merkittävä osa julkisen internetin liikenteestä on automatisoitua: hakukoneita, tekoälyindeksoijia, agentteja, tiedonkeruuohjelmia, haavoittuvuusskannereita ja vähemmän hyväntahtoisia botteja. Osa tästä liikenteestä on hyödyllistä, osa ei.

Kun sovellukset olivat suoraan Cloudflaren takana, tiukensimme tietoturvasääntöjämme niin, että haitallinen automatisoitu liikenne voitiin torjua reunaverkossa ennen kuin se aiheutti sovelluksille laskentaa tai tietokantatyötä.

Sen jälkeen kokonaissäästömme nousivat noin 90 %:iin vanhaan ratkaisuun verrattuna.

Lopullinen kustannusten lasku syntyi usean tekijän yhteisvaikutuksesta: Cloudflaren edullisemmasta hinnoittelusta, etenkin tiedonsiirron osalta; vähäisemmästä palvelinpuolen työstä; rajapinnoillemme paremmin sopivasta suoritusympäristöstä; selkeämmin määritellystä välimuistituksesta; ja siitä, että sovelluksiin pääsi ylipäätään vähemmän turhia pyyntöjä.

Mihin päädyimme

Repositoriossamme ei ole enää yhtään Next.js-sovellusta. Useimmat verkkosovelluksemme ovat nyt Viteen ja TanStack Routeriin perustuvia SPA-sovelluksia Cloudflare Workersissa. webcatalog.io ja lexibird.com käyttävät TanStack Startia Cloudflare Workersissa, koska nämä sivustot todella hyötyvät SSR:stä. Rajapintamme käyttävät Honoa ja tRPC:tä Railwayssa tavallisina Node.js-kontteina. Lähes kaikki frontend-projektimme kuuluvat nyt Vite-ekosysteemiin.

Infrastruktuurikustannuksemme laskivat noin 80 %. Cloudflaren liikenteellemme huomattavasti edullisempi hinnoittelu, etenkin tiedonsiirron osalta, vaikutti siihen merkittävästi. Haitallisen automatisoidun liikenteen suodattaminen reunaverkossa kasvatti kokonaissäästöt noin 90 %:iin.

Meille tärkein lopputulos liittyy kuitenkin arkkitehtuuriin. Markkinointisivustot saavat SSR:n, kaikki sovellukset, jotka voivat olla SPA-sovelluksia, ovat SPA-sovelluksia, ja rajapinnat toimivat oikeilla palvelimilla silloin, kun se on yksinkertaisempaa.

Aloitimme yrittämällä tehdä Vercelistä halvemman.

Lopulta ymmärsimme, ettemme tarvinneet suurinta osaa arkkitehtuurista, josta maksoimme.