Deploy build browser-heavy dengan rollback dan SLO yang jelas tidak bisa diperlakukan seperti deploy aplikasi web biasa yang hanya mengganti HTML, CSS, dan beberapa bundle JavaScript kecil. Pada aplikasi seperti demo game 3D, WebAssembly, viewer besar, atau workload grafis di browser, satu rilis dapat membawa aset ratusan megabyte, dependency yang sensitif terhadap versi, dan perilaku klien yang baru terlihat setelah file lama dan baru bercampur di cache pengguna.

Masalah utamanya bukan hanya “apakah deploy sukses”, tetapi apakah pengguna memuat kombinasi file yang konsisten, apakah CDN menayangkan versi yang benar, apakah browser klien sanggup menjalankan build baru tanpa lonjakan CPU berlebihan, dan apakah tim bisa rollback sebelum error menyebar luas. Karena itu, strategi deploy harus dibangun di sekitar tiga hal: versioned assets, release bertahap, dan SLO serta observability yang eksplisit.

Mengapa browser-heavy lebih berisiko saat deploy

Pada aplikasi web browser-heavy, artefak rilis biasanya tidak hanya terdiri dari satu bundle. Ada HTML shell, manifest, JavaScript bootstrap, WebAssembly, texture, audio, mesh, shader, worker script, dan kadang paket data besar yang diunduh terpisah. Kegagalan sering muncul saat file-file ini tidak lagi sinkron.

Risiko yang paling sering terjadi

  • Cache/CDN stale: HTML terbaru mereferensikan aset baru, tetapi edge cache masih menyajikan file lama, atau sebaliknya.
  • Asset mismatch: manifest menunjuk ke hash baru, tetapi sebagian klien masih memakai bootstrap lama yang mengharapkan struktur lama.
  • Lonjakan bandwidth: rilis baru memaksa banyak pengguna mengunduh ulang aset besar secara bersamaan.
  • CPU browser meningkat: perubahan shader, decoding asset, atau startup pipeline baru menaikkan penggunaan CPU dan memicu freeze, tab crash, atau timeout.
  • Error observability terlambat: server tampak sehat, tetapi browser gagal saat inisialisasi setelah asset besar selesai diunduh.

Kesalahan umum tim adalah hanya memantau availability origin server. Pada workload browser-heavy, masalah paling mahal justru bisa berada di sisi delivery dan runtime klien.

Prinsip arsitektur release yang aman

1. Pisahkan shell aplikasi dari aset versi

Prinsip paling penting adalah: jangan overwrite aset lama dengan nama yang sama. Semua file statis yang berpotensi di-cache lama harus memiliki identitas versi yang unik, biasanya lewat hash konten atau direktori release.

Contoh struktur yang aman:

/releases/2026-06-25T1000/index.html
/assets/app.8f3c2.js
/assets/runtime.91ab4.js
/assets/game-data.a12d9.pak
/assets/engine.4bc22.wasm
/manifest.json

Atau:

/builds/2026-06-25-1000/
  index.html
  manifest.json
  app.js
  engine.wasm
  textures.pack

Yang penting bukan formatnya, melainkan sifatnya:

  • Aset lama tetap tersedia selama masa transisi rollback.
  • HTML/manifest hanya menunjuk ke satu set artefak yang konsisten.
  • Rollback cukup mengubah pointer ke release sebelumnya, bukan menyalin ulang file satu per satu.

2. Treat HTML sebagai control plane, aset sebagai data plane

HTML utama, JSON bootstrap, atau endpoint konfigurasi kecil sebaiknya menjadi pintu kontrol rilis. File ini dapat berubah lebih sering dan memakai TTL rendah. Sebaliknya, file besar seperti .wasm, .pak, texture, atau bundle hashed dapat diberi cache panjang karena namanya sudah immutable.

Pola cache yang lazim:

  • HTML/bootstrap/manifest: TTL pendek, revalidation agresif.
  • Hashed assets: TTL panjang, immutable.

Tujuannya agar klien cepat “melihat” release baru, tetapi file versi lama tetap aman dilayani jika masih direferensikan.

3. Jangan menjadikan purge CDN sebagai strategi utama konsistensi

Purge cache berguna, tetapi bukan fondasi release. Purge bisa lambat, tidak serentak di semua edge, dan rawan race condition. Jika konsistensi rilis Anda bergantung pada purge total, maka rollback juga akan lambat dan berisiko.

Lebih aman memakai:

  • nama file unik per versi,
  • release pointer yang bisa dipindah cepat,
  • retensi artefak lama untuk jangka waktu tertentu.

Strategi deploy build browser-heavy yang praktis

Tahap 1: Upload artefak secara atomik

Upload seluruh artefak release ke lokasi versi baru terlebih dahulu. Jangan mengubah traffic pengguna sebelum semua file selesai, checksum sesuai, dan permission/metadata cache benar.

Checklist minimum:

  • Semua file terunggah lengkap.
  • Manifest sesuai isi artefak.
  • File besar seperti .wasm atau paket data dapat diunduh utuh.
  • Header cache untuk shell dan hashed assets sudah benar.
  • Release lama masih tersedia.

Tahap 2: Validasi pre-release dari edge, bukan hanya origin

Pengujian yang hanya mengambil file dari origin belum cukup. Uji jalur yang sama dengan pengguna nyata:

  • akses lewat CDN,
  • simulasi cold cache,
  • simulasi browser baru membuka sesi,
  • cek bahwa bootstrap memuat semua subresource yang benar.

Jika memungkinkan, pakai smoke test yang benar-benar memuat halaman, menunggu engine/asset dasar selesai inisialisasi, lalu memastikan state minimal tercapai.

Tahap 3: Release bertahap dengan feature flag atau traffic gating

Untuk browser-heavy, rollout bertahap lebih berguna daripada cutover penuh. Tujuannya bukan hanya mengurangi risiko error, tetapi juga membatasi ledakan bandwidth jika cache miss terjadi serentak.

Pendekatan yang umum:

  • Feature flag berbasis user segment: hanya sebagian pengguna yang mendapat release baru.
  • Canary by cookie/header: internal, QA, atau persentase kecil user dipaksa ke release tertentu.
  • Geographic rollout: buka region kecil dulu jika CDN dan origin dipisah per wilayah.
  • Entry-point gating: halaman utama tetap lama, halaman preview memakai release baru.

Jika Anda sudah memiliki gateway atau edge logic, sangat membantu untuk mengontrol release lewat satu pointer, misalnya versi aktif di cookie, KV store, atau config service.

{
  "active_release": "2026-06-25-1000",
  "canary_release": "2026-06-25-1200",
  "canary_percent": 5
}

Logika pemilihannya dapat dilakukan di edge atau aplikasi bootstrap. Yang penting, keputusan versi harus deterministik per sesi agar satu pengguna tidak berganti-ganti release di tengah jalan.

Tahap 4: Health check yang relevan dengan browser-heavy

Health check tidak cukup hanya memeriksa HTTP 200 pada root path. Minimal, buat health check yang menguji:

  • HTML shell dapat dimuat.
  • Manifest release valid dan mengarah ke file yang ada.
  • Aset inti seperti runtime.js, engine.wasm, atau paket data dasar mengembalikan 200/206 yang benar.
  • Subresource penting tidak menghasilkan 404.
  • Smoke test browser dapat mencapai state “ready”.

Untuk file besar, dukungan range request juga patut dicek jika alur unduh Anda bergantung padanya.

SLO dan metrik inti yang harus jelas

Tanpa SLO, deploy sering dinilai “aman” hanya karena tidak ada alarm besar dari server. Untuk browser-heavy, SLO perlu menangkap pengalaman rilis dari sisi delivery dan startup klien.

SLO minimum yang realistis

  • TTFB untuk HTML/bootstrap tidak boleh memburuk tajam setelah rilis.
  • Error rate untuk permintaan dokumen, JavaScript, WebAssembly, dan API bootstrap harus stabil.
  • Asset 404 rate harus mendekati nol. Kenaikan kecil saja bisa menandakan mismatch versi.
  • Cache hit ratio di CDN tidak boleh jatuh drastis melebihi pola release yang sudah diantisipasi.
  • Startup success rate atau browser-ready rate harus dipantau jika Anda punya instrumentasi klien.

Anda tidak harus memulai dengan target numerik yang terlalu rumit. Yang penting adalah ada ambang rollback yang disepakati sebelum deploy dimulai.

Metrik inti yang sebaiknya dikumpulkan

  • TTFB per route penting: terutama HTML utama dan bootstrap JSON.
  • HTTP status per tipe aset: dokumen, JS, CSS, WASM, paket data, worker.
  • Asset 404 by release: sangat penting untuk mendeteksi referensi silang antarversi.
  • Cache hit/miss ratio per path class: shell vs immutable asset.
  • Bandwidth egress dan request rate di CDN/origin.
  • Client startup error: error inisialisasi engine, fetch failure, exception saat instantiate WASM, shader compile failure jika diinstrumentasi.
  • Abort/cancel rate: berguna untuk melihat pengguna meninggalkan sesi saat unduhan awal terlalu berat.

Contoh event logging dari klien

Logging klien sederhana sering jauh lebih berguna daripada menunggu laporan manual dari pengguna.

{
  "event": "startup_failed",
  "release": "2026-06-25-1200",
  "phase": "wasm_init",
  "asset": "/assets/engine.4bc22.wasm",
  "http_status": 200,
  "message": "instantiate failed",
  "user_agent": "redacted",
  "session_id": "abc123"
}

Jangan kirim data berlebihan. Fokus pada field yang membantu korelasi:

  • release/version,
  • phase startup,
  • asset path atau asset class,
  • status HTTP jika ada,
  • pesan error yang dinormalisasi,
  • session/request identifier.

Versioned assets, cache policy, dan mencegah asset mismatch

Pola header cache yang aman

Contoh prinsip konfigurasi:

  • index.html atau bootstrap kecil: cache pendek atau revalidate.
  • app.[hash].js, engine.[hash].wasm, data.[hash].pak: cache panjang dan immutable.

Ilustrasi kebijakan:

# HTML / bootstrap
Cache-Control: no-cache

# Hashed immutable assets
Cache-Control: public, max-age=31536000, immutable

Nilai tepatnya bisa mengikuti kebijakan platform Anda, tetapi polanya sebaiknya tetap sama: shell fleksibel, aset versi immutable.

Manifest harus terikat ke satu release

Masalah klasik adalah manifest baru menunjuk sebagian file baru, sementara file lain masih dihasilkan atau belum terdistribusi. Solusinya:

  • generate manifest setelah artefak final siap,
  • simpan manifest di direktori release yang sama,
  • jangan expose manifest sebelum semua dependensi tersedia.

Jika satu release punya banyak bundle dan paket data, lebih aman jika semua referensi berasal dari satu manifest pusat yang versi-nya eksplisit.

Hindari referensi “latest” untuk aset besar

Path seperti /assets/latest/engine.wasm tampak nyaman, tetapi membuat cache dan rollback sulit diprediksi. Nama yang tidak immutable meningkatkan peluang klien memuat campuran file lama dan baru.

Gunakan path versi atau hash. Biarkan hanya entry point kecil yang menunjuk release aktif.

Rollback cepat: desain sebelum insiden terjadi

Rollback yang baik bukan prosedur manual panjang. Ia harus menjadi operasi kecil yang mengubah pointer release dan menghentikan ekspansi blast radius.

Karakteristik rollback yang baik

  • Tidak perlu rebuild.
  • Tidak perlu purge total sebagai syarat berhasil.
  • Tidak perlu upload ulang aset lama.
  • Dapat dilakukan dalam hitungan menit atau lebih cepat.
  • Dapat diverifikasi lewat smoke test yang sama dengan deploy.

Pola rollback yang direkomendasikan

  1. Set release baru ke status canary atau nonaktif.
  2. Ubah pointer entry point ke release stabil sebelumnya.
  3. Pertahankan aset release bermasalah untuk kebutuhan investigasi, jangan langsung dihapus.
  4. Monitor apakah metrik kembali normal.

Jika memakai edge config, rollback bisa sesederhana mengganti nilai release aktif. Jika memakai object storage/CDN, HTML shell atau bootstrap config adalah titik pengendali yang paling praktis.

Kapan harus rollback, bukan menunggu

Tentukan syarat rollback sebelum deploy. Misalnya:

  • Asset 404 meningkat konsisten selama beberapa menit.
  • Error startup klien naik setelah rollout persentase kecil.
  • Cache hit ratio anjlok dan origin mulai tertekan.
  • TTFB HTML/bootstrap memburuk sehingga startup melambat signifikan.

Tanpa kriteria ini, tim cenderung berdebat terlalu lama saat insiden berlangsung.

Logging, alerting, dan deteksi dini

Alert yang benar-benar berguna

Untuk deploy browser-heavy, alert berikut biasanya lebih cepat mendeteksi masalah daripada error rate API umum:

  • Asset 404 per release
  • Cache hit ratio drop pada kelas aset besar
  • Spike bandwidth egress yang tidak sesuai ekspektasi rollout
  • Client startup failure rate
  • TTFB degradation untuk HTML/bootstrap

Alert sebaiknya diberi dimensi release. Tanpa label release, Anda akan sulit membedakan apakah error berasal dari deploy baru atau masalah lama yang belum beres.

Struktur logging yang membantu investigasi

Baik log edge, origin, maupun klien, usahakan memiliki field berikut:

  • release
  • asset_type seperti html, js, wasm, pack, worker
  • cache_status bila tersedia
  • status_code
  • request_id atau trace id
  • region atau POP jika memakai CDN global

Dengan struktur ini, pertanyaan seperti “release mana yang menghasilkan 404 untuk file WASM di region tertentu?” bisa dijawab jauh lebih cepat.

Contoh alur deployment yang aman

  1. Build artefak dan hasilkan nama file immutable.
  2. Upload semua aset ke lokasi release baru.
  3. Validasi integritas, manifest, dan smoke test melalui CDN.
  4. Aktifkan release untuk internal/QA.
  5. Rollout 1-5% trafik dengan feature flag atau canary.
  6. Pantau TTFB, asset 404, cache hit ratio, startup error, dan bandwidth.
  7. Jika stabil, naikkan bertahap ke 25%, 50%, lalu 100%.
  8. Jika ada sinyal buruk, rollback dengan mengubah pointer release aktif.
  9. Simpan release lama sampai periode aman lewat.

Alur ini mungkin terasa lebih lambat daripada deploy biasa, tetapi jauh lebih murah dibanding rollback panik setelah jutaan request ke asset besar terlanjur tersebar.

Runbook insiden ringan untuk deploy browser-heavy

Trigger insiden

  • Asset 404 meningkat setelah rollout.
  • Startup error klien naik pada release baru.
  • Bandwidth origin/CDN melonjak tidak wajar.
  • Cache miss tinggi menyebabkan TTFB memburuk.

Langkah respons 15 menit pertama

  1. Freeze rollout: hentikan kenaikan persentase release baru.
  2. Bandingkan berdasarkan release: cek apakah error terlokalisasi ke build terbaru.
  3. Periksa 404 dan manifest: cari file yang direferensikan tetapi tidak tersedia.
  4. Verifikasi cache behavior: cek apakah HTML/bootstrap dan asset immutable mengikuti kebijakan yang benar.
  5. Rollback jika ambang terlewati: jangan menunggu semua data sempurna.
  6. Jalankan smoke test setelah rollback: pastikan release stabil benar-benar aktif.
  7. Komunikasikan status: ringkas, faktual, dan menyebut dampak pengguna.

Pertanyaan diagnostik cepat

  • Apakah hanya release baru yang gagal?
  • Apakah masalah terjadi di semua region atau hanya sebagian edge?
  • Apakah 404 muncul pada file hashed tertentu?
  • Apakah browser memuat HTML baru tetapi asset lama, atau sebaliknya?
  • Apakah lonjakan bandwidth berasal dari cache bust massal yang tidak direncanakan?
  • Apakah error muncul sebelum atau sesudah unduhan asset besar selesai?

Template postmortem singkat

Judul:
Insiden deploy browser-heavy release 2026-06-25-1200

Ringkasan:
Release baru menyebabkan peningkatan startup failure dan asset 404 pada sebagian pengguna.

Timeline:
- 10:00 deploy artefak selesai
- 10:10 canary 5% dimulai
- 10:14 alert asset 404 meningkat
- 10:18 rollback dilakukan
- 10:24 metrik kembali normal

Dampak:
- Pengguna pada canary gagal startup atau mengalami loading gagal
- Origin/CDN mengalami kenaikan traffic akibat cache miss

Akar masalah:
- Manifest release terekspos sebelum seluruh aset tersedia di edge

Faktor yang memperparah:
- Alert startup klien terlambat
- Tidak ada verifikasi smoke test dari beberapa region CDN

Tindakan perbaikan:
- Tambah gate publikasi manifest setelah verifikasi aset lengkap
- Tambah alert asset 404 per release
- Tambah rollout step lebih kecil untuk aset besar

Pemilik dan tenggat:
- DevOps: perbaiki pipeline release pointer
- Frontend platform: tambah client telemetry startup

Tindakan pencegahan agar rilis berikutnya lebih aman

  • Wajibkan versioned immutable assets untuk semua file yang bisa di-cache panjang.
  • Pertahankan beberapa release sebelumnya agar rollback tidak bergantung pada restore darurat.
  • Tambahkan smoke test berbasis browser, bukan hanya cek status HTTP.
  • Gunakan rollout bertahap default untuk build besar, jangan menjadikannya pengecualian.
  • Instrumentasikan startup klien sampai fase “ready”, bukan hanya page view.
  • Label semua metrik dengan release agar korelasi insiden cepat.
  • Dokumentasikan ambang rollback sebelum deploy dimulai.
  • Latih rollback saat tidak ada insiden, supaya prosedur tidak baru dicoba saat panik.

Penutup

Deploy build browser-heavy yang aman bukan soal satu tool tertentu, melainkan disiplin release: aset harus berversi, rollout harus bertahap, metrik harus relevan, dan rollback harus cepat. Jika aplikasi Anda memuat WebAssembly, bundle besar, texture, atau data game di browser, risiko utamanya ada pada konsistensi artefak dan visibilitas error klien, bukan semata uptime server.

Mulailah dari fondasi yang paling berdampak: versioned assets, cache policy yang benar, feature flag/canary, alert asset 404 dan cache hit ratio, serta runbook rollback yang singkat. Dengan itu, tim DevOps dapat merilis build besar dengan blast radius yang terkendali dan keputusan rollback yang tidak lagi berdasarkan tebakan.