Bagaimana Migrasi dari Vercel ke Cloudflare Workers + Railway Memangkas Biaya Infrastruktur Web Kami hingga 80%

Kami memigrasikan stack web kami dari Vercel ke Cloudflare Workers dan Railway, mengganti Next.js dengan kombinasi TanStack Router, TanStack Start, dan Hono sesuai kebutuhan masing-masing beban kerja. Hasilnya, biaya infrastruktur turun sekitar 80%, lalu penghematannya meningkat menjadi sekitar 90% setelah lalu lintas otomatis yang berbahaya disaring di edge. Sebagian besar pekerjaan migrasi dilakukan oleh agen AI untuk pemrograman, sementara para engineer berfokus pada arsitektur, batasan, peninjauan, dan verifikasi di lingkungan produksi.

23 September 2026

Quang Lam · Founder & CEO

Bagaimana Migrasi dari Vercel ke Cloudflare Workers + Railway Memangkas Biaya Infrastruktur Web Kami hingga 80%

Selama bertahun-tahun, Vercel menjadi pilihan utama kami untuk men-deploy hampir semua layanan web di WebCatalog. Sebagian besar proyek itu menggunakan Next.js, jadi keduanya cocok secara alami. Situs pemasaran, antarmuka produk, pengaturan akun, konsol developer, autentikasi, alat admin, dan API kami semuanya menggunakan stack yang kurang lebih sama.

Pendekatan itu bekerja dengan baik untuk waktu yang lama. Vercel memudahkan deployment, Next.js menyediakan framework full-stack yang membuat kami produktif, dan kami jarang perlu memikirkan infrastruktur di balik keduanya.

Pada akhirnya, kemudahan itu tidak lagi sesuai dengan kebutuhan produk kami.

Situs pemasaran kami masih mendapat manfaat dari SSR (server-side rendering), tetapi sebagian besar aplikasi web kami yang lain tidak. Aplikasi-aplikasi itu bisa berupa SPA (single-page application) biasa. API kami membutuhkan lingkungan Node.js standar dengan dependensi native dan proses yang berjalan terus-menerus. Hampir seluruh bagian lain dari stack frontend kami sudah menggunakan Vite. Pada saat yang sama, biaya infrastruktur semakin sulit diabaikan, terutama seiring meningkatnya trafik publik dan otomatis.

Awalnya, kami mencoba mengoptimalkan apa yang sudah ada. Kami mempertimbangkan untuk tetap menggunakan Next.js dan memindahkannya ke Cloudflare Workers melalui adaptor. Kami mencoba Astro untuk situs pemasaran. Kami juga sempat menjalankan API di Cloudflare Containers.

Pada akhirnya, kami memilih susunan yang lebih sederhana: sebagian besar aplikasi web kami kini menggunakan Vite + TanStack Router di Cloudflare Workers, situs pemasaran kami menggunakan TanStack Start dengan SSR di Cloudflare Workers, dan API kami menggunakan Hono + tRPC di Railway sebagai kontainer Node.js yang berjalan terus-menerus.

Migrasi ini menurunkan biaya infrastruktur web kami sekitar 80%. Setelah kami juga memperketat aturan keamanan Cloudflare dan memblokir lebih banyak trafik otomatis yang berbahaya di edge, total penghematannya meningkat menjadi sekitar 90%.

Sebagian besar implementasi migrasi juga dikerjakan oleh agen AI untuk coding, terutama Claude Fable 5 dan Claude Opus 5, sementara para engineer menentukan arsitektur, menetapkan batasan, meninjau perubahan, dan memverifikasi hasilnya.

Kami Tidak Langsung Meninggalkan Vercel

Naluri pertama kami adalah mengoptimalkan sistem yang sudah ada.

webcatalog.io menjadi titik awal yang paling jelas karena menerima banyak trafik publik, sementara sebagian besar halamannya relatif jarang berubah. Kami mendapati terlalu banyak bagian situs yang masih dirender secara dinamis. Karena itu, kami memperbaiki rendering dinamis yang tidak disengaja, menambahkan ISR (Incremental Static Regeneration) pada rute dengan trafik tinggi, membuat lebih banyak halaman dapat di-cache, dan mengoptimalkan proses sitemap yang mahal.

Pekerjaan itu membantu, tetapi juga membuat masalah mendasarnya semakin jelas. Kami menghabiskan semakin banyak waktu untuk memahami mengapa konten yang relatif statis dirender secara dinamis, perilaku framework apa yang menyebabkannya, dan mekanisme framework apa yang perlu kami tambahkan agar konten itu dapat di-cache lagi.

Sementara itu, banyak aplikasi kami yang lain justru menghadapi situasi sebaliknya. Pengaturan akun, konsol developer, aplikasi admin, dan sebagian besar antarmuka produk sama sekali tidak memerlukan rendering di server. Semuanya adalah aplikasi browser yang berkomunikasi dengan API.

Pada titik itu, pertanyaannya bukan lagi “Bagaimana cara mengecilkan tagihan Vercel kami?” melainkan “Apa yang akan kami bangun jika aplikasi-aplikasi ini sejak awal tidak menggunakan Next.js?”

Kami Mempertimbangkan Next.js di Cloudflare

Opsi yang paling sedikit mengganggu adalah tetap menggunakan Next.js dan memindahkannya dari Vercel ke Cloudflare Workers.

Kami mempertimbangkannya dengan serius karena Next.js dapat berjalan di Cloudflare melalui lapisan adaptor, sehingga sebagian besar struktur aplikasi yang ada bisa dipertahankan.

Namun, kami tidak menganggap Next.js di Cloudflare setara dengan Next.js di Vercel. Next.js terintegrasi paling erat dengan runtime, sistem deployment, perilaku caching, dan fitur platform Vercel. Di Cloudflare, adaptor harus menerjemahkan asumsi-asumsi tersebut ke runtime yang berbeda.

Pendekatan itu bisa berjalan dengan baik, tetapi jika tujuan kami adalah menyederhanakan stack, menambahkan satu lagi lapisan kompatibilitas terasa kurang ideal.

Ada juga persoalan tooling yang lebih luas. Hampir semua hal lain yang kami bangun di frontend sudah menggunakan Vite: aplikasi desktop, ekstensi browser, SPA, dan proyek sisi klien lainnya.

Next.js telah banyak beralih ke Turbopack, dan Turbopack telah berkembang pesat. Ini bukan keluhan soal performa. Bagi kami, perbedaan yang lebih penting adalah ekosistemnya. Vite sudah menjadi fondasi bersama bagi sebagian besar codebase frontend kami, dengan ekosistem plugin yang lebih luas dan konfigurasi yang lebih mudah digunakan kembali di berbagai proyek.

Jadi, mempertahankan Next.js di Cloudflare akan menyelesaikan sebagian masalah hosting, tetapi tetap mempertahankan ketidakselarasan framework dan ekosistem build tool yang terpisah.

Karena itu, kami mengambil langkah mundur dan melihat apa yang sebenarnya dibutuhkan oleh tiap jenis beban kerja.

Kami Membagi Stack Berdasarkan Beban Kerja

Setelah berhenti mencari satu pengganti universal untuk Next.js, arsitekturnya menjadi jauh lebih sederhana.

Situs pemasaran kami membutuhkan SSR karena memiliki halaman publik dalam berbagai bahasa, metadata, URL kanonis, sitemap, dan trafik dari mesin pencari.

Sebagian besar aplikasi web kami yang lain tidak membutuhkan SSR dan cukup menjadi aplikasi Vite yang menggunakan TanStack Router.

API kami sama sekali tidak membutuhkan framework React dan lebih cocok dijalankan di runtime Node.js standar.

Pembagian akhirnya seperti ini:

Aplikasi web
Vite + TanStack Router
        │
        └── Cloudflare Workers

Situs pemasaran
TanStack Start + SSR
        │
        └── Cloudflare Workers

API
Hono + tRPC
        │
        └── Kontainer Railway / Node.js

Prinsipnya menjadi jelas: gunakan SSR ketika benar-benar memberikan manfaat, gunakan SPA biasa ketika tidak, dan jalankan layanan backend di runtime backend.

Sebagian Besar Aplikasi Web Menjadi SPA

Migrasi SPA adalah bagian yang paling mudah.

Aplikasi web WebCatalog berpindah dengan sangat cepat: kami menyiapkan kerangka pengganti dengan Vite + TanStack Router, memindahkan antarmukanya, mengalihkan deployment ke Cloudflare Workers, dan menghapus versi Next.js lama pada pagi yang sama.

Kami mengulangi pola yang sama untuk aplikasi web Lexibird, pengaturan akun, konsol developer, autentikasi, dan aplikasi admin. Dari pembuatan kerangka SPA pertama hingga penghapusan aplikasi Next.js terakhir, prosesnya memakan waktu sekitar 19 hari.

Untuk aplikasi-aplikasi ini, Cloudflare Workers sengaja kami gunakan dengan cara yang sederhana. Vite membangun aset statis, Cloudflare menyajikannya, dan rute aplikasi menggunakan index.html sebagai fallback. Tidak ada runtime SSR karena memang tidak ada yang perlu dirender di server.

Bagian yang lebih sulit adalah mempertahankan perilaku yang telah terbentuk di sekitar aplikasi-aplikasi itu dari waktu ke waktu. Sebagian logika autentikasi harus dipindahkan dari rute server Next.js ke API, dan versi lama aplikasi desktop WebCatalog masih bergantung pada endpoint lama yang harus tetap berfungsi.

Memindahkan UI React itu mudah.

Mempertahankan kontrak yang sudah ada lebih sulit.

Kami Mencoba Astro dan Menghapusnya Lima Hari Kemudian

Situs pemasaran lebih sulit ditangani.

Pilihan pertama kami adalah Astro, yang tampak cocok untuk webcatalog.io dan lexibird.com karena keduanya merupakan situs publik dengan banyak konten, dan Astro terintegrasi dengan baik dengan Cloudflare.

Kami mulai memindahkan kedua situs itu, lalu berhenti lima hari kemudian.

Tidak ada satu kelemahan fatal. Sebaliknya, ketidakcocokan kecil terus menumpuk. Beberapa rute memerlukan akses database saat prerendering, sedangkan lingkungan build kami memang sengaja tidak memiliki kredensial database produksi. React islands membuat pengelolaan state bersama di seluruh aplikasi terasa kurang alami. Kami juga menemui perbedaan antara rute yang di-prerender dan rute yang dirender saat runtime, serta beberapa kendala tooling di repositori kami.

Tak satu pun dari masalah itu mustahil diselesaikan. Justru karena itulah melanjutkannya berisiko. Kami bisa saja menghabiskan beberapa minggu lagi untuk memperbaiki masalah satu demi satu.

Sebagai gantinya, kami menghapus implementasi tersebut dan memulai lagi.

Agen AI mengubah perhitungan di balik keputusan itu. Sebagian besar pekerjaan pemindahan yang bersifat mekanis tidak menyita waktu engineer selama berminggu-minggu, sehingga biaya yang sudah telanjur dikeluarkan lebih kecil dan kami lebih mudah mengakui bahwa kami lebih menyukai arsitektur lain.

TanStack Start Lebih Cocok

Kami memulai ulang migrasi situs pemasaran dari kode Next.js asli, kali ini menggunakan TanStack Start.

Pilihan ini terasa jauh lebih alami karena kami sudah menggunakan TanStack Router di aplikasi SPA. Dengan demikian, routing, loader, parameter pencarian, dan navigasi mengikuti konsep yang serupa. Kodenya tetap berupa React dan TypeScript biasa, dan sistem build-nya adalah Vite.

Kami memindahkan lexibird.com ke TanStack Start dalam sehari. webcatalog.io menyusul.

Keunggulannya bukan karena TanStack Start secara ajaib menyelesaikan semua masalah. Keunggulannya adalah kesesuaiannya dengan arah stack kami yang lain.

Dalam monorepo, hal itu penting. Build tool bersama berarti lebih banyak plugin dan konfigurasi yang dapat digunakan kembali, lebih sedikit kasus khusus saat debugging, lebih sedikit perpindahan konteks bagi developer, dan lebih sedikit konvensi khusus proyek yang harus dipahami oleh agen coding.

Cloudflare Jauh Lebih Murah untuk Pola Trafik Kami

Arsitektur hanya salah satu alasan tagihan kami turun. Harga Cloudflare merupakan faktor utama, terutama untuk bandwidth.

Paket Workers Paid dari Cloudflare saat ini mengenakan biaya terutama berdasarkan jumlah request dan penggunaan CPU, serta tidak menambahkan biaya transfer data atau bandwidth untuk Workers. (developers.cloudflare.com) Ini sangat berarti bagi situs web publik karena sebuah request mungkin hanya menggunakan sedikit CPU, tetapi tetap mentransfer HTML, JavaScript, gambar, font, dan aset lainnya.

Model harga Vercel juga mencakup kategori penggunaan dan alokasi terkait jaringan, termasuk Fast Data Transfer dan Fast Origin Transfer. (vercel.com) Untuk profil trafik kami, struktur biaya Cloudflare jauh lebih menguntungkan.

Penghematan itu tidak hanya berasal dari pergantian penyedia. Kami juga memindahkan banyak aplikasi ke hasil build Vite yang statis, mengurangi SSR yang tidak perlu, membuat aturan caching lebih eksplisit, dan memindahkan beban kerja API ke runtime yang lebih cocok. Namun, harga Cloudflare, khususnya terkait bandwidth, merupakan penyumbang besar bagi penurunan sekitar 80% yang kami alami.

Angka itu berlaku khusus untuk beban kerja kami. Ini bukan klaim bahwa setiap aplikasi yang berpindah dari Vercel ke Cloudflare akan menghemat 80%.

API Kami Berakhir di Railway

API adalah persoalan tersendiri.

Meski berupa proyek Next.js, API kami sebenarnya sudah cukup independen dari Next.js. API WebCatalog terdiri dari sekitar 34.000 baris kode, tetapi hanya tujuh file yang mengimpor next/server. tRPC sudah menggunakan adaptor Fetch, dan Inngest mendukung Hono.

Kami mengganti lapisan HTTP Next.js dengan Hono. Bagian itu ternyata sangat kecil.

Pertanyaan yang lebih sulit adalah di mana API tersebut harus dijalankan. Workers biasa kurang cocok karena API kami menggunakan Node.js dan dependensi native seperti sharp.

Awalnya, kami mencoba Cloudflare Containers, yang memungkinkan kami segera keluar dari Vercel. Namun, setelah menjalankan konfigurasi itu di produksi, kami mendapati model operasionalnya memerlukan lebih banyak penyesuaian kapasitas secara manual daripada yang kami inginkan saat itu.

Jadi, kami memindahkan API sekali lagi.

Kini API kami berjalan di Railway sebagai layanan kontainer Node.js biasa yang beroperasi terus-menerus. CI (continuous integration) membangun image Docker, mengirimkannya ke registry kami, dan Railway menangani autoscaling horizontal.

Tidak semuanya harus berjalan di edge.

Meninggalkan Vercel Berarti Mengambil Alih Lebih Banyak Tanggung Jawab

Biaya yang lebih rendah datang dengan konsekuensi.

Vercel dan Next.js sebelumnya menangani banyak perilaku infrastruktur pada tingkat yang lebih tinggi. Dengan TanStack Start dan Workers, kami beralih ke caching HTTP yang eksplisit. Sebuah halaman dirender, kami mengembalikan header cache, lalu Cloudflare menyimpan responsnya di cache. Kebijakan cache browser dan edge dapat berbeda, termasuk penggunaan stale-while-revalidate di edge.

Kami menyukai keputusan-keputusan yang kini dibuat secara eksplisit, tetapi infrastruktur yang eksplisit juga berarti kesalahannya menjadi tanggung jawab kami sendiri.

Kami melakukan beberapa kesalahan. Satu aturan cache di produksi tanpa sengaja mencakup respons fungsi server TanStack yang spesifik untuk tiap pengunjung, dan konfigurasi cache lain berinteraksi buruk dengan perilaku fallback SPA. Bug-bug itu menjadi pengingat bahwa kebenaran hasil migrasi tidak dapat dibuktikan sepenuhnya hanya dari repositori. Infrastruktur produksi juga merupakan bagian dari sistem.

Agen AI Mengubah Cara Kami Bermigrasi

Sebagian besar pekerjaan implementasi dilakukan oleh agen coding, terutama Claude Fable 5 dan Claude Opus 5.

Migrasi framework sangat cocok dikerjakan oleh agen karena sebagian besar pekerjaannya memiliki acuan yang jelas dari implementasi lama. Pindahkan rute ini, pertahankan URL ini, ganti API framework ini, jaga agar metadatanya tetap sama, jalankan pemeriksaan tipe, perbaiki error, dan bandingkan hasilnya dengan implementasi lama.

Untuk webcatalog.io, kami memelihara pelacak migrasi yang membagi pekerjaan ke tahap-tahap seperti fondasi, halaman produk, halaman katalog, pencarian, blog, harga, pengalihan, sitemap, dan peralihan akhir. Alih-alih meminta agen untuk “memigrasikan webcatalog.io ke TanStack Start”, kami memberinya tugas-tugas terbatas dengan hal-hal yang secara eksplisit harus tetap dipertahankan.

Aplikasi yang sudah ada menjadi spesifikasinya. Tugas agen adalah mereproduksi perilaku dengan arsitektur baru, bukan merancang ulang produknya.

Hal itu mengalihkan upaya manusia dari menerjemahkan kode secara manual ke pertanyaan seperti: Apakah halaman ini benar-benar perlu SSR? Perilaku mana yang memang disengaja? Apa yang boleh di-cache secara global? URL mana yang harus tetap persis sama? Di mana autentikasi harus dilakukan? Kapan kami harus berhenti mencoba membuat suatu pendekatan berhasil?

Kami tetap meninjau hasilnya, menjalankan build dan pemeriksaan tipe, serta memverifikasi secara manual area berisiko lebih tinggi seperti autentikasi, SEO (search engine optimization), pengalihan, dan caching.

Perubahan pentingnya bukan sekadar AI menulis kode untuk kami. AI membuat eksperimen menjadi lebih murah.

Mencoba Astro lalu menghapusnya setelah lima hari menjadi jauh lebih mudah dibenarkan. Memindahkan API sekali, lalu memutuskan bahwa platform lain lebih cocok, juga tidak terlalu menyakitkan. Karena pekerjaan mekanis menjadi lebih murah, kami bisa mengubah arah ketika arsitekturnya tidak tepat, alih-alih terus melanjutkan hanya karena sudah berinvestasi terlalu banyak.

Agen membuat kapasitas implementasi tidak lagi terlalu langka.

Hal itu membuat arsitektur, batasan, peninjauan, dan verifikasi menjadi semakin penting.

Penghematan 80% Menjadi Sekitar 90%

Setelah migrasi, biaya infrastruktur web kami turun sekitar 80%.

Kemudian, kami mulai lebih memperhatikan request mana saja yang mencapai aplikasi.

Sebagian besar trafik internet publik bersifat otomatis: berasal dari mesin pencari, crawler AI, agen, scraper, pemindai, dan bot yang kurang bersahabat. Sebagian trafik itu bermanfaat, sebagian lagi tidak.

Dengan aplikasi yang berada langsung di belakang Cloudflare, kami memperketat aturan keamanan agar trafik otomatis yang berbahaya dapat ditolak di edge sebelum memicu komputasi aplikasi atau pekerjaan database.

Setelah itu, total penghematan kami mencapai sekitar 90% dibandingkan dengan sistem lama.

Penurunan akhirnya berasal dari beberapa hal yang bekerja bersama: harga Cloudflare yang lebih rendah, terutama untuk bandwidth; lebih sedikit pekerjaan di sisi server; runtime yang lebih cocok untuk API kami; caching yang lebih eksplisit; serta lebih sedikit request yang tidak perlu mencapai aplikasi.

Hasil Akhirnya

Tidak ada lagi aplikasi Next.js di repositori kami. Sebagian besar aplikasi web kami kini berupa SPA Vite + TanStack Router di Cloudflare Workers. webcatalog.io dan lexibird.com menggunakan TanStack Start di Cloudflare Workers karena kedua situs itu benar-benar mendapat manfaat dari SSR. API kami menggunakan Hono + tRPC di Railway, berjalan sebagai kontainer Node.js biasa. Hampir semua proyek frontend kami kini berada dalam ekosistem Vite.

Biaya infrastruktur kami turun sekitar 80%, dengan struktur biaya Cloudflare yang jauh lebih menguntungkan untuk trafik kami, khususnya bandwidth, sebagai penyumbang besar. Penyaringan trafik otomatis yang berbahaya di edge meningkatkan penghematan keseluruhan menjadi sekitar 90%.

Namun, hasil yang paling kami hargai adalah arsitekturnya. Situs pemasaran mendapatkan SSR, semua yang bisa menjadi SPA dijadikan SPA, dan API berjalan di server biasa ketika server biasa merupakan pilihan yang lebih sederhana.

Kami memulai dengan mencoba membuat Vercel lebih murah.

Kami berakhir dengan menyadari bahwa sebagian besar arsitektur yang selama ini kami bayar ternyata tidak kami butuhkan.