karawaci.kode

2026-08-02 · 10 min

PlanetScale Mati Free Tier: Neon vs Supabase vs Railway Postgres 2026

PlanetScale menutup free tier-nya, dan migration path-nya tidak sesederhana ganti connection string karena kita bicara pindah dari MySQL-Vitess ke PostgreSQL. Saya sudah evaluasi tiga kandidat teratas untuk klien dan project internal: Neon, Supabase, dan Railway Postgres — dan kesimpulannya tidak selalu sama untuk setiap situasi.

Kenapa Ini Bukan Sekadar “Cari PlanetScale yang Murah”

PlanetScale bukan cuma managed MySQL. Proposisi nilainya adalah:

  1. Branching-based schema migration — tidak ada DDL langsung ke production, semua lewat branch yang bisa di-merge.
  2. Scale tanpa foreign key — Vitess partisi data secara horizontal, dan FK dikorbankan untuk itu.
  3. Connection pooling built-in — PlanetScale proxy menangani ribuan koneksi di belakang layar.

Kalau Anda pindah ke Postgres, foreign key kembali tersedia (dan kali ini Anda mungkin mau pakainya), schema migration perlu tooling baru (Flyway, Liquibase, atau Drizzle migrations), dan connection pooling perlu dipikirkan sendiri.

Ketiga kandidat ini punya filosofi berbeda — pahami dulu mana yang cocok dengan arsitektur Anda.

Neon: Serverless Postgres dengan Branching Native

Neon dibangun dari awal sebagai serverless Postgres. Storage dan compute dipisah: storage tetap hidup, compute bisa scale-to-zero. Ini yang memungkinkan branching instan — branch baru adalah pointer ke storage yang sama (copy-on-write), bukan salinan data baru.

Connection Pooling di Neon

Neon punya connection pooler built-in (PgBouncer) yang diakses via endpoint pooled:

# Direct connection (batas: ~100 koneksi sesuai tier)
postgres://user:[email protected]/neondb

# Pooled connection (rekomendasi untuk aplikasi)
postgres://user:[email protected]/neondb?pgbouncer=1

Satu gotcha: pooled endpoint pakai transaction mode PgBouncer secara default. Ini berarti SET LOCAL, advisory lock, dan prepared statement dengan nama tidak bisa diandalkan antar query. Kalau Anda pakai Prisma, tambahkan connection_limit=1&pool_timeout=20 di connection string dan biarkan Prisma’s own connection pool kerja di atas pooled endpoint.

// prisma/schema.prisma — datasource untuk Neon + pooling
datasource db {
  provider  = "postgresql"
  url       = env("DATABASE_URL")       // pooled endpoint
  directUrl = env("DATABASE_URL_DIRECT") // direct endpoint untuk migrations
}

Dua env var ini penting: DATABASE_URL untuk query runtime (via pooler), directUrl untuk prisma migrate deploy karena migration DDL tidak bisa jalan di transaction mode pooler.

Branching untuk Preview Environment

Ini fitur terkuat Neon untuk tim dengan CI/CD. Setiap PR bisa dapat database branch sendiri:

# Install Neon CLI
npm install -g neonctl

# Buat branch dari main untuk PR #42
neonctl branches create --name preview/pr-42 --parent main

# Dapat connection string branch ini
neonctl connection-string preview/pr-42

# Hapus setelah PR di-merge
neonctl branches delete preview/pr-42

Di production kami, ini diintegrasikan ke GitHub Actions: branch dibuat saat PR dibuka, dihapus saat di-merge atau di-close. Tim frontend bisa test dengan data production-like tanpa takut merusak production.

Cold Start: Realita di Production

Scale-to-zero berarti ada biaya cold start. Pengukuran saya di region aws-ap-southeast-1 (Singapore):

  • Cold start setelah idle 5 menit: ~300-450ms untuk query pertama
  • Query berikutnya: normal (1-5ms untuk simple query)

Untuk aplikasi SaaS dengan traffic continuous, ini tidak jadi masalah. Untuk cron job atau webhook jarang — perhatikan ini. Di plan Scale ke atas, Anda bisa matikan auto-suspend per compute endpoint.

Harga Neon (2026):

  • Free: 0.5 GB storage, 1 project, auto-suspend aktif
  • Launch ($19/bulan): 10 GB storage, branching, matikan auto-suspend
  • Scale ($69/bulan): 50 GB, multiple compute, PITR 7 hari

Supabase: Full Platform, Bukan Sekadar Database

Supabase adalah PostgreSQL plus Auth, Storage, Edge Functions, dan Realtime dalam satu platform. Kalau Anda butuh hanya database, ini overkill. Kalau Anda butuh stack lengkap, ini menghemat waktu drastis.

Connection Pooling di Supabase

Supabase punya dua mode koneksi:

# Direct: port 5432 — untuk migrations, tidak lewat pooler
postgresql://postgres:[password]@db.xxxx.supabase.co:5432/postgres

# Pooler Transaction mode: port 6543 — untuk aplikasi runtime
postgresql://postgres.[project-ref]:[password]@aws-0-ap-southeast-1.pooler.supabase.com:6543/postgres

# Pooler Session mode: port 5432 via pooler — kalau butuh session-level features
postgresql://postgres.[project-ref]:[password]@aws-0-ap-southeast-1.pooler.supabase.com:5432/postgres

Supabase Pooler berbasis Supavisor (Elixir-based, bukan PgBouncer). Di benchmark internal saya, throughput-nya sedikit lebih baik dari PgBouncer untuk workload concurrent tinggi, tapi perbedaannya tidak dramatis untuk traffic normal.

RLS: Kekuatan yang Sering Dilewatkan

Row Level Security adalah fitur Postgres native yang Supabase dorong habis-habisan — dan benar, ini mengubah cara Anda menulis authorization logic:

-- Enable RLS pada tabel
ALTER TABLE transactions ENABLE ROW LEVEL SECURITY;

-- Policy: user hanya bisa lihat transaksi miliknya sendiri
CREATE POLICY "transactions_user_isolation"
  ON transactions
  FOR ALL
  USING (auth.uid() = user_id);

Dengan RLS, query SELECT * FROM transactions dari client yang ter-auth otomatis hanya mengembalikan data milik user tersebut — tanpa WHERE user_id = $1 eksplisit di setiap query. Ini powerful untuk multi-tenant, tapi ada ongkos: performance RLS policy perlu dimonitor. Policy yang tidak ter-index bisa jadi bottleneck di tabel besar.

Supabase Tidak Gratis untuk Production

Ini yang sering mengejutkan: Supabase Free tier cukup terbatas dan database di-pause setelah 7 hari tidak aktif. Untuk production:

  • Pro ($25/bulan): 8 GB database, daily backups, tidak di-pause. Ini minimum untuk production nyata.
  • Team ($599/bulan): SOC 2, PITR, dedicated support — untuk enterprise.

Supabase Pro $25 ini adalah benchmark yang perlu Anda bandingkan dengan Neon Launch $19.

Railway Postgres: Simplicity Tanpa Fitur Eksotis

Railway adalah platform deployment (seperti Heroku modern) yang juga menyediakan managed Postgres. Tidak ada serverless, tidak ada branching, tidak ada fitur eksotis — ini Postgres biasa yang berjalan di container.

Setup di Railway

# Tambah Postgres service ke project Railway
railway add --plugin postgresql

# Connect dari service lain di project yang sama
# Railway inject DATABASE_URL otomatis ke environment
echo $DATABASE_URL
# postgresql://postgres:[email protected]:xxxxx/railway

Connection string Railway bisa diakses dari luar network Railway juga (via public proxy), tapi untuk koneksi internal antar service di Railway yang sama, gunakan private networking:

# Internal (lebih cepat, tidak keluar network)
postgresql://postgres:[email protected]:5432/railway

Tidak ada built-in connection pooler di Railway. Untuk aplikasi Node.js, Anda perlu kelola pool sendiri via library:

import { Pool } from 'pg';

const pool = new Pool({
  connectionString: process.env.DATABASE_URL,
  max: 20,           // sesuaikan dengan plan Railway Anda
  idleTimeoutMillis: 30000,
  connectionTimeoutMillis: 2000,
});

Atau deploy PgBouncer sebagai service terpisah di Railway jika butuh ratusan koneksi.

Harga Railway Postgres (2026):

  • Hobby ($5/bulan base + usage): $0.000231/GB-hour storage, $0.000463/vCPU-second. Untuk database kecil idle, bisa jadi ~$7-15/bulan.
  • Pro: sama tapi dengan higher limits dan SLA lebih baik.

Harga Railway lebih transparan tapi lebih sulit diprediksi dibanding flat rate Neon/Supabase.

Perbandingan Langsung

FiturNeonSupabaseRailway
EnginePostgres (serverless)Postgres (persistent)Postgres (persistent)
Connection PoolingBuilt-in (PgBouncer)Built-in (Supavisor)Manual / deploy sendiri
Cold StartAda (scale-to-zero)Tidak adaTidak ada
BranchingNative, matureBeta 2026Tidak ada
Auth built-inTidakYaTidak
Storage/CDN built-inTidakYaTidak
Edge FunctionsTidakYaTidak
Harga production entry$19/bulan$25/bulan~$10-20/bulan (usage-based)
PITR7 hari (Scale tier)7 hari (Pro tier)Tidak ada (backup manual)
Region Indonesia/SEASingapore (AWS)Singapore (AWS)Tidak tersedia, closest: US/EU

Railway tidak punya region Asia Tenggara — ini deal-breaker untuk aplikasi yang butuh latency rendah ke user Indonesia. Neon dan Supabase keduanya ada di Singapore.

Verdict: Pilih Berdasarkan Konteks

Pilih Neon jika:

  • Kebutuhan utama adalah database branching untuk preview environments
  • Tim developer aktif dan butuh isolasi database per PR
  • Budget terbatas, tidak butuh Auth/Storage dari provider
  • Aplikasi punya traffic continuous (cold start bukan masalah) atau siap bayar plan yang matikan auto-suspend

Pilih Supabase jika:

  • Butuh Auth + Database + Storage dalam satu platform
  • Tim kecil yang tidak mau manage multiple services
  • Fitur Realtime (WebSocket via Postgres replication) relevan untuk produk Anda
  • RLS cocok dengan model authorization aplikasi Anda

Pilih Railway Postgres jika:

  • Sudah deploy compute di Railway dan ingin satu billing/platform
  • Butuh Postgres vanilla tanpa behaviour serverless
  • Aplikasi Anda tidak butuh region Asia Tenggara (atau target user bukan Indonesia)

Untuk klien Jakarta yang migrasi dari PlanetScale, rekomendasi default saya adalah Supabase Pro $25 — paling mendekati pengalaman “managed, production-ready, tidak perlu mikir infrastruktur” yang dulunya diberikan PlanetScale. Neon adalah alternatif kuat jika branching/preview environment adalah prioritas dan Anda tidak butuh ekosistem Auth/Storage Supabase.

Railway hanya masuk kalau seluruh stack sudah di Railway dan latency ke Asia bukan concern — itu kondisi yang jarang terpenuhi untuk produk Indonesia.

Satu hal yang pasti: migrasi dari PlanetScale ke Postgres lebih dari sekadar ganti URL koneksi. Luangkan waktu untuk audit query, tambahkan index yang tepat setelah FK aktif, dan test connection pooling behaviour sebelum cut-over production.

Ditulis oleh Reza Pradipta