Menjalankan Next.js pada skala puluhan hingga ratusan juta request per bulan menghadirkan dilema arsitektur: tetap menggunakan ekosistem managed Vercel atau mengelola kluster Kubernetes (K8s) sendiri. Vercel memberikan kecepatan iterasi tanpa friksi operasional, tetapi biaya bandwidth egress dan komputasi fungsi serverless melonjak secara non-linear pada skala besar. Di sisi lain, self-hosting Next.js dengan kontainer di Kubernetes menuntut penanganan manual terhadap state terdistribusi seperti Incremental Static Regeneration (ISR) dan optimasi aset.

Arsitektur Runtime: Managed Edge vs Standalone Node.js

Vercel memecah aplikasi Next.js ke dalam komponen infrastruktur terpisah saat proses build: rute statis didelegasikan ke Global CDN, API/SSR dialokasikan ke AWS Lambda, dan middleware berjalan di Edge Runtime (V8 isolates). Skalabilitas horizontal terjadi otomatis tanpa perlu mengelola concurrency server.

Pada Kubernetes, Next.js dijalankan menggunakan output standalone dalam kontainer Docker berbasis Node.js. Satu proses Node.js menangani SSR, API routes, routing middleware, dan optimasi gambar secara bersamaan. Pendekatan ini mengubah paradigma arsitektur dari ephemeral micro-functions menjadi long-running stateful services di dalam Pod.

Tantangan Teknis Self-Hosting di Kubernetes

1. ISR Terdistribusi Multi-Pod via Cache Handler

Secara default, cache ISR disimpan di sistem berkas lokal pod (.next/cache). Pada kluster multi-pod di balik Ingress Controller, request yang memicu regenerasi halaman hanya akan memperbarui disk pod penerima. Pod lain akan tetap melayani halaman lama atau mengalami status stale yang tidak konsisten.

Untuk mengatasinya, delegasikan penyimpanan cache ke layer terpusat (Redis atau Shared Object Storage) menggunakan custom cacheHandler.

// cache-handler.js
const { createClient } = require('redis');

const client = createClient({ url: process.env.REDIS_URL });
client.connect().catch(console.error);

class CacheHandler {
  constructor(options) {
    this.options = options;
  }

  async get(key) {
    const data = await client.get(`next-cache:${key}`);
    if (!data) return null;
    return JSON.parse(data);
  }

  async set(key, data, ctx) {
    // Simpan payload HTML/JSON dan metadata TTL
    const payload = JSON.stringify({ value: data, lastModified: Date.now() });
    if (ctx?.tags?.length) {
      // Indexing tags untuk on-demand revalidation
      await Promise.all(ctx.tags.map(tag => client.sAdd(`tag:${tag}`, key)));
    }
    await client.set(`next-cache:${key}`, payload, {
      EX: ctx?.revalidate ? ctx.revalidate : 86400,
    });
  }

  async revalidateTag(tag) {
    const keys = await client.sMembers(`tag:${tag}`);
    if (keys.length) {
      await client.del(keys.map(k => `next-cache:${k}`));
      await client.del(`tag:${tag}`);
    }
  }
}

module.exports = CacheHandler;

Daftarkan handler ini pada next.config.js:

// next.config.js
module.exports = {
  output: 'standalone',
  cacheHandler: process.env.NODE_ENV === 'production' 
    ? require.resolve('./cache-handler.js') 
    : undefined,
};

2. Overhead Image Optimization di Dalam Pod

Komponen next/image memanfaatkan pustaka C sharp/libvips untuk kompresi dan transformasi gambar secara on-the-fly. Operasi ini bersifat CPU-bound dan memory-intensive. Jika ribuan request gambar masuk bersamaan ke Pod SSR yang sama, event loop Node.js akan terblokir, latensi TTFB melonjak, dan Pod berisiko terkena OOMKilled (Out of Memory) oleh K8s.

Mitigasi pada K8s skala besar:

  • Isolasi Deployment: Buat deployment Pod terpisah khusus untuk menangani rute /_next/image, terpisah dari Pod penyaji SSR/API.
  • Offload ke Dedicated CDN/Service: Atur konfigurasi loader kustom ke layanan pihak ketiga (Cloudflare Images, Imgix, AWS Serverless Image Handler), lalu nonaktifkan optimasi bawaan via images: { unoptimized: true } jika beban komputasi internal tidak ekonomis.

3. Eksekusi Middleware: Edge Isolate vs Node.js Event Loop

Di Vercel, middleware berjalan di edge network sebelum request mencapai infrastruktur inti. Di K8s standalone, middleware berjalan langsung di runtime Node.js pod Anda sebelum rute dievaluasi. Kode middleware yang tidak efisien (misalnya validasi JWT kriptografis berat atau panggilan I/O sinkron) akan langsung mendegradasi throughput server secara menyeluruh. Batasi middleware container hanya untuk manipulasi header ringan atau autentikasi berbasis delegasi gateway (seperti Envoy Ingress external auth).

Analisis Total Cost of Ownership (TCO)

Penilaian finansial tidak boleh hanya membandingkan tagihan tagihan Vercel dengan biaya instance EC2/Compute Engine. Analisis harus mencakup infrastruktur dan alokasi jam kerja tim engineering.

Komponen BiayaVercel (Managed)Self-Hosted Kubernetes
Egress BandwidthTinggi ($0.15 - $0.30 per GB setelah kuota paket enterprise).Rendah (Biaya standar Cloud Provider ~$0.05 - $0.09 per GB, gratis jika di-cache Cloudflare/Fastly).
Compute UnitServerless execution duration (GB-hours) memiliki markup margin tinggi.Sangat murah melalui EC2 Spot Instances / Graviton / Karpenter autoscaling.
Infrastruktur PendukungTermasuk (Global CDN, Log storage dasar, SSL, WAF).Terpisah (Biaya ALB/Ingress, Redis cluster, NAT Gateway, S3, OTel collector).
Engineering OverheadSangat rendah. Tidak membutuhkan tim DevOps dedikasi untuk layer frontend.Tinggi. Memerlukan SRE untuk patch security base image, manajemen helm chart, tuning HPA, dan incident on-call.

Titik impas (break-even point) finansial umumnya tercapai ketika volume bandwidth egress bulanan melampaui 10–20 TB atau ketika tim telah memiliki kluster Kubernetes produksi yang sudah matang untuk layanan backend.

Isolasi Jaringan dan Observabilitas

Privasi VPC dan Akses Database Internal

Salah satu hambatan struktural Vercel pada arsitektur enterprise adalah kebutuhan mengakses backend internal (misal: microservices gRPC, internal database, Kafka). Vercel memerlukan konfigurasi Secure Compute atau Direct VPC Peering yang terbatas pada paket Enterprise bertarif premium.

Pada Kubernetes, Pod Next.js berada langsung di dalam subnet privat VPC yang sama dengan microservices backend. Komunikasi berjalan melalui protokol internal berlatensi sub-milidetik tanpa biaya data transfer out publik dan tanpa membuka port database ke internet.

Observabilitas: Turnkey vs OpenTelemetry

Vercel menyediakan analitik bawaan untuk Core Web Vitals dan log runtime. Namun, korelasi distributed tracing lintas layanan membutuhkan forwarder log eksternal. Di Kubernetes, aplikasi standalone Next.js dapat diinstrumentasikan secara natif menggunakan OpenTelemetry SDK:

// instrumentation.ts
export async function register() {
  if (process.env.NEXT_RUNTIME === 'nodejs') {
    const { NodeSDK } = await import('@opentelemetry/sdk-node');
    const { getNodeAutoInstrumentations } = await import('@opentelemetry/auto-instrumentations-node');
    const { OTLPTraceExporter } = await import('@opentelemetry/exporter-trace-otlp-grpc');

    const sdk = new NodeSDK({
      traceExporter: new OTLPTraceExporter({ url: 'grpc://otel-collector.monitoring:4317' }),
      instrumentations: [getNodeAutoInstrumentations()],
    });

    sdk.start();
  }
}

Konfigurasi ini memberikan visibilitas metrik Prometheus, status APM, dan distributed tracing yang terpadu langsung ke dashboard Grafana atau Datadog perusahaan.

Matriks Keputusan: Vercel vs Kubernetes

Gunakan kriteria teknis berikut untuk menentukan arsitektur hosting Next.js Anda:

  1. Pilih Vercel jika:
    • Tim frontend independen dan tidak memiliki SRE/DevOps berdedikasi.
    • Aplikasi sangat mengandalkan kapabilitas edge rendering global dan optimasi statis di seluruh dunia.
    • Tingkat perubahan kode tinggi dan fitur Preview Deployment per git branch menjadi penentu kecepatan rilis.
    • Biaya egress dan komputasi bulanan masih berada di bawah alokasi gaji tahunan 1 orang SRE senior.
  2. Pilih Self-Hosted Kubernetes jika:
    • Aplikasi memproses traffic skala masif dengan konsumsi egress bandwidth puluhan terabyte per bulan.
    • Frontend membutuhkan latensi sangat rendah ke API backend/database yang berada di private VPC yang sama tanpa melalui internet publik.
    • Perusahaan telah memiliki infrastruktur K8s matang dengan pipeline CI/CD, monitoring Prometheus/OpenTelemetry, dan tim on-call 24/7 yang siap menangani insiden runtime.
    • Kebutuhan kepatuhan data ketat (regulasi perbankan/kesehatan) yang melarang transmisi data melalui multi-tenant proxy pihak ketiga.