Blue-green vs canary deployments: membuat perubahan API dan DB lebih aman
Perbandingan blue-green dan canary untuk perubahan API dan database, dengan langkah praktis untuk mengurangi risiko downtime saat migrasi skema dan klien mobile yang lambat.

Mengapa deployment jadi berisiko saat ada perubahan skema dan update mobile yang lambat
Sebuah deploy bisa tampak sempurna di pengujian tapi tetap gagal saat menerima lalu lintas nyata. Penyebab umum adalah kode Anda bukan satu-satunya yang berubah. Kontrak API dan skema database juga berubah, dan mereka jarang berubah pada kecepatan yang sama.
Masalah muncul ketika bagian sistem yang berbeda tidak sepaham tentang apa yang dianggap "benar". Backend baru mengharapkan kolom yang belum ada. Backend lama menulis data dalam format yang tidak lagi dimengerti kode baru. Bahkan perubahan kecil seperti mengganti nama field, memperketat validasi, atau mengubah nilai enum bisa menyebabkan error di produksi.
Aplikasi mobile meningkatkan taruhannya karena versi lama tetap ada. Beberapa pengguna memperbarui dalam hitungan menit, yang lain butuh minggu. Itu berarti backend harus melayani beberapa generasi klien sekaligus. Jika Anda merilis perubahan API yang hanya bekerja dengan aplikasi terbaru, Anda bisa merusak proses checkout, onboarding, atau sinkronisasi latar belakang bagi sebagian pengguna tanpa langsung menyadarinya.
"Risiko downtime" bukan hanya situs yang mati. Dalam sistem nyata, sering muncul sebagai kegagalan parsial:
- lonjakan error 4xx/5xx di endpoint tertentu sementara yang lain tampak normal
- gagalnya sign-in karena token, peran, atau record user tidak sesuai ekspektasi
- masalah data sunyi (default salah, teks terpotong, relasi hilang) yang baru terlihat beberapa hari kemudian
- pekerjaan background macet dan membangun antrean yang butuh jam untuk dikuras
Inilah sebabnya tim membandingkan blue-green vs canary deployments: Anda ingin mengurangi blast radius saat perubahan tidak sepenuhnya kompatibel.
Blue-green dan canary dengan bahasa sederhana
Saat orang membandingkan blue-green vs canary deployments, biasanya mereka menjawab satu pertanyaan: apakah Anda mau switch besar yang terkontrol, atau tes kecil yang hati-hati?
Blue-green: dua versi penuh dan satu sakelar lalu lintas
Blue-green berarti menjalankan dua lingkungan lengkap secara bersamaan. "Blue" adalah versi saat ini yang melayani pengguna. "Green" adalah versi baru, dideploy dan diuji secara paralel. Saat siap, Anda mengalihkan lalu lintas dari blue ke green.
Pendekatan ini bagus untuk prediktabilitas. Anda bisa memvalidasi versi baru dengan pengaturan mirip produksi sebelum melayani pengguna nyata, lalu melakukan cutover yang bersih.
Rollback juga sederhana: jika ada masalah setelah switch, arahkan kembali lalu lintas ke blue. Ini hampir instan, tetapi cache, pekerjaan background, dan perubahan data masih bisa membuat pemulihan lebih rumit.
Canary: kirim sebagian kecil lalu lintas terlebih dahulu
Canary berarti versi baru hidup untuk sebagian kecil pengguna atau request dulu. Jika terlihat sehat, tingkatkan persentasenya langkah demi langkah sampai melayani semua.
Canary cocok saat Anda khawatir perilaku yang tidak diketahui pada lalu lintas nyata. Anda bisa menangkap masalah lebih awal, sebelum sebagian besar pengguna merasakannya.
Rollback dilakukan dengan mengurangi persentase canary kembali ke nol (atau menghentikan routing ke versi baru). Biasanya cepat, tapi tidak selalu bersih, karena beberapa pengguna mungkin sudah membuat data atau state yang harus ditangani kedua versi.
Cara sederhana mengingat trade-off:
- Blue-green mendukung cutover yang bersih dan switchback cepat.
- Canary mendukung pembelajaran dari lalu lintas nyata dengan blast radius terbatas.
- Tidak ada yang otomatis memperbaiki risiko database. Jika perubahan skema tidak kompatibel, keduanya bisa gagal.
- Canary tergantung pada monitoring karena keputusan dibuat berdasarkan sinyal live.
- Blue-green sering butuh kapasitas ekstra karena menjalankan dua stack penuh.
Contoh: jika Anda merilis API yang kadang mengembalikan field baru, canary membantu melihat apakah klien lama crash karena data tak terduga. Jika perubahan membutuhkan penggantian nama kolom yang tidak bisa ditangani kode lama, blue-green tidak akan menyelamatkan Anda kecuali perubahan skema dirancang untuk mendukung kedua versi.
Apa yang membuat migrasi database berbeda dari deploy kode
Deploy kode biasanya mudah di-rollback. Jika versi baru bermasalah, Anda redeploy build lama dan sebagian besar kembali seperti semula.
Perubahan database berbeda karena mengubah bentuk data Anda. Setelah baris ditulis ulang, kolom dihapus, atau constraint diperketat, kembali bukan lagi instan. Bahkan jika Anda rollback kode aplikasi, kode lama mungkin tidak memahami skema baru.
Itulah mengapa risiko downtime migrasi skema seringkali lebih terkait dengan bagaimana migrasi dirancang daripada metode deployment.
Dasar migrasi online
Migrasi paling aman dibangun agar bekerja sementara versi lama dan baru berjalan bersamaan. Polanya sederhana: buat perubahan yang aman untuk diabaikan, update kode untuk menggunakannya, lalu bersihkan nanti.
Urutan expand-then-contract yang umum seperti ini:
- Perubahan additif dulu: tambahkan kolom nullable, tabel baru, tambahkan indeks tanpa mengunci penulisan jika memungkinkan.
- Perilaku ganda: tulis ke lama dan baru, atau baca dari baru dengan fallback ke lama.
- Backfill terpisah: migrasikan data lama dalam batch kecil.
- Switch over: alihkan sebagian besar lalu lintas ke perilaku baru.
- Perubahan destruktif terakhir: drop kolom lama, hapus path kode lama, perketat constraint.
Migrasi "big bang" menggabungkan langkah paling berisiko dalam satu rilis: lock panjang, backfill besar, dan kode yang mengasumsikan skema baru ada di mana-mana.
Mengapa update mobile yang lambat menaikkan standar
Klien mobile bisa tetap pada versi lama selama berminggu-minggu. Backend Anda harus terus menerima request lama dan mengembalikan response lama sementara database berevolusi.
Jika aplikasi lama mengirim request tanpa field baru, server Anda tidak bisa tiba-tiba menjadikan field itu wajib di database. Anda perlu periode di mana kedua perilaku berjalan.
Strategi mana yang mengurangi risiko downtime untuk migrasi skema
Pilihan paling aman lebih bergantung pada satu pertanyaan: bisakah versi lama dan baru berjalan dengan benar pada skema database yang sama untuk sementara waktu?
Jika jawabannya ya, blue-green sering menjadi opsi dengan downtime terendah. Anda bisa menyiapkan perubahan database dulu, menjaga lalu lintas pada stack lama, lalu switch traffic ke stack baru dalam satu cutover. Jika ada yang salah, Anda cepat switch kembali.
Blue-green masih gagal ketika aplikasi baru membutuhkan skema baru segera. Contoh umum termasuk menghapus atau mengganti nama kolom yang masih dibaca versi lama, atau menambahkan constraint NOT NULL sebelum aplikasi menulis nilai. Dalam kasus itu, rollback mungkin tidak aman karena database sudah tidak kompatibel.
Canary lebih baik saat Anda butuh pembelajaran terkendali. Sebagian kecil lalu lintas nyata mengenai versi baru dulu, membantu mendeteksi edge case seperti indeks yang hilang, pola query tak terduga, atau pekerjaan background yang berperilaku berbeda di bawah beban produksi. Trade-off-nya adalah Anda harus menjaga kedua versi bekerja bersamaan, yang biasanya berarti perubahan database yang kompatibel mundur.
Aturan keputusan praktis
Saat menimbang blue-green vs canary untuk risiko downtime migrasi skema:
- Pilih blue-green ketika Anda bisa menjaga perubahan skema bersifat additif dan kompatibel, dan Anda terutama menginginkan switch yang cepat dan bersih.
- Pilih canary ketika Anda tidak yakin bagaimana perubahan berperilaku di produksi, atau Anda mengharapkan bentuk data langka berdampak.
- Jika migrasi memaksa perubahan yang langsung merusak, jangan pilih antara blue-green dan canary. Ubah rencana menjadi expand-then-contract.
Bentuk "kompatibel" dalam praktik
Misal Anda menambah field baru pada tabel orders. Jalur aman: tambahkan kolom sebagai nullable, deploy aplikasi yang menulisnya, backfill baris lama, lalu setelah itu tegakkan constraint. Dalam setup itu, blue-green memberi cutover yang bersih, dan canary memberi peringatan dini jika ada path kode yang masih mengasumsikan bentuk lama.
Bagaimana update mobile yang lambat mengubah pilihan deployment
Pengguna web menyegarkan halaman. Pengguna mobile tidak.
Di iOS dan Android, orang bertahan pada versi lama selama minggu atau bulan. Beberapa tidak pernah memperbarui sampai aplikasi memaksa, dan beberapa perangkat offline lama. Itu berarti klien "lama" masih memanggil API lama jauh setelah backend baru dirilis. Klien mobile lama menjadi uji permanen untuk kompatibilitas balik Anda.
Ini menggeser tujuan dari "deploy tanpa downtime" menjadi "menjaga beberapa generasi klien bekerja bersamaan." Dalam praktiknya, mobile sering mendorong pola pikir ala canary untuk API, meskipun Anda mungkin menggunakan blue-green untuk infrastruktur.
Perubahan kompatibel balik vs versioning API
Kebanyakan waktu, Anda ingin perubahan kompatibel balik karena memungkinkan klien lama dan baru berbagi endpoint yang sama.
Contoh kompatibel balik: menambahkan field baru, menerima bentuk payload lama dan baru, menjaga field response yang ada, dan menghindari perubahan makna. Versioning API berguna ketika perilaku harus berubah (bukan sekadar menambah data), atau ketika Anda harus menghapus atau mengganti nama field.
Contoh: menambahkan field opsional marketing_opt_in biasanya aman. Mengubah cara price dihitung biasanya tidak.
Merencanakan jendela deprecasi
Jika Anda perlu perubahan yang memutus kompatibilitas, perlakukan akhir dukungan seperti keputusan produk. Jendela deprecasi yang berguna diukur berdasarkan "pengguna aktif yang masih di versi lama," bukan hari kalender.
Urutan praktis:
- Rilis backend yang mendukung klien lama dan baru.
- Rilis app baru dan lacak adopsi berdasarkan versi app.
- Beri peringatan atau batasi hanya ketika versi lama turun di bawah ambang aman.
- Hapus perilaku lama terakhir, dengan rencana rollback.
Langkah demi langkah: pola rollout aman untuk perubahan API + database
Saat Anda mengubah API dan database bersamaan, rencana paling aman biasanya rollout dua atau tiga tahap. Setiap langkah harus aman dideploy sendiri, bahkan jika pengguna tetap memakai app mobile lama selama berminggu-minggu.
Pola rollout yang menghindari memutus klien lama
Mulai dengan perubahan database additif. Tambah kolom atau tabel baru, hindari mengganti nama atau menghapus, izinkan null bila perlu, dan gunakan default agar kode lama tidak tiba-tiba kena constraint.
Kemudian kirim kode aplikasi yang mentolerir kedua bentuk data. Read harus menerima "field lama hilang" dan "field baru hadir." Write harus terus menulis field lama untuk saat ini, dan opsional juga menulis field baru.
Urutan tipikal:
- Tambah potongan skema baru (kolom, tabel, indeks) tanpa menghapus yang lama.
- Deploy kode yang membaca dari lama atau baru dan tidak crash pada null.
- Backfill baris yang ada dalam batch kecil, lalu verifikasi jumlah, rate null, dan performa query.
- Alihkan jalur penulisan ke field baru, tetapkan fallback untuk membaca.
- Setelah versi mobile lama menghilang, hapus field lama dan bersihkan kode.
Backfill dan verifikasi: tempat outage tersembunyi
Backfill sering gagal karena dianggap skrip cepat. Jalankan bertahap, pantau beban, dan verifikasi hasil. Jika perilaku baru butuh indeks, tambahkan sebelum mengganti read atau write, bukan setelah.
Contoh: Anda menambahkan phone_country_code untuk memperbaiki format. Pertama tambahkan kolom (nullable), update API agar menerimanya tapi tetap bekerja kalau tidak ada, backfill dari nomor telepon yang ada, lalu mulai menulis untuk signup baru. Minggu kemudian, ketika versi lama hampir hilang, Anda bisa menghapus jalur parsing legacy.
Alat yang membuat kedua strategi lebih aman (tanpa ribet)
Anda tidak perlu setup rumit untuk membuat blue-green vs canary lebih aman. Beberapa kebiasaan mengurangi kejutan saat API dan skema database bergerak pada kecepatan berbeda.
Dual-read dan dual-write (jadikan sementara)
Dual-write berarti aplikasi menulis data ke tempat lama dan baru selama transisi (mis. users.full_name dan users.display_name). Dual-read berarti bisa membaca dari mana saja, biasanya memilih field baru tapi fallback ke yang lama.
Ini memberi waktu untuk update klien yang lambat, tapi harus jembatan pendek. Tentukan bagaimana Anda akan menghapusnya, lacak jalur yang dipakai (baru vs fallback), dan tambahkan pemeriksaan dasar agar kedua write tetap konsisten.
Feature flags untuk perubahan perilaku
Feature flag memungkinkan Anda mendeploy kode tanpa mengaktifkan perilaku berisiko. Itu membantu baik untuk blue-green maupun canary karena Anda bisa memisahkan "deploy" dari "aktifkan."
Contoh: deploy dukungan untuk field response baru, tapi tetap kembalikan shape lama sampai siap. Lalu aktifkan untuk grup kecil, amati error, dan tingkatkan. Jika ada yang rusak, matikan flag tanpa redeploy.
Mindset contract testing (API adalah janji)
Banyak insiden migrasi sebenarnya bukan masalah database. Mereka adalah masalah ekspektasi klien.
Perlakukan API seperti janji. Hindari menghapus field atau mengubah makna. Buat field tak dikenal menjadi opsional. Perubahan additif (field baru, endpoint baru) biasanya aman. Perubahan yang memutus harus menunggu versi API baru.
Job migrasi data yang bisa dipercaya
Migrasi skema sering membutuhkan job backfill untuk menyalin data, menghitung nilai, atau membersihkan. Job ini harus membosankan dan dapat diulang: aman dijalankan dua kali, bisa retry, mudah dilacak, dan dibatasi supaya tidak memicu lonjakan beban.
Kesalahan umum yang menyebabkan outage saat migrasi
Sebagian besar outage migrasi terjadi ketika rilis mengasumsikan semua bergerak bersama: semua layanan dideploy bersamaan, semua data bersih, dan semua klien update tepat waktu. Sistem nyata tidak bekerja seperti itu, terutama dengan mobile.
Pola kegagalan umum:
- Menghapus atau mengganti nama kolom terlalu awal. Kode API lama, pekerjaan background, atau app mobile lama mungkin masih menggunakannya.
- Mengasumsikan klien cepat update. Rilis mobile butuh waktu untuk menjangkau pengguna, dan banyak orang tidak mengupdate segera.
- Menjalankan migrasi yang mengunci tabel besar saat jam puncak. Indeks atau perubahan kolom sederhana bisa memblokir penulisan.
- Menguji hanya data contoh yang bersih. Data produksi punya null, format aneh, duplikat, dan nilai legacy.
- Tidak punya rencana rollback nyata untuk kode dan data. "Kita bisa redeploy versi sebelumnya" tidak cukup jika skema sudah berubah.
Contoh: Anda mengganti nama status menjadi order_status dan deploy API baru. Web app berfungsi. Klien mobile lama masih mengirim status, dan sekarang API menolak request tersebut, menyebabkan gagal checkout. Jika Anda sudah menghapus kolomnya, mengembalikan perilaku bukan switch cepat.
Default yang lebih baik: buat perubahan dalam langkah kecil yang reversible, jaga jalur lama dan baru bekerja bersama, dan tuliskan apa yang akan dilakukan jika metrik melambung (cara merutekan kembali traffic, feature flag mana mematikan perilaku baru, dan bagaimana memvalidasi serta memperbaiki data jika backfill bermasalah).
Daftar cek cepat sebelum Anda deploy
Beberapa pengecekan sebelum rilis menangkap masalah yang menyebabkan rollback malam hari. Ini paling penting saat Anda mengubah API dan database sekaligus, terutama dengan update mobile yang lambat.
Lima pemeriksaan yang mencegah sebagian besar outage
- Kompatibilitas: pastikan versi aplikasi lama dan baru sama-sama bekerja terhadap skema database yang sama. Tes praktis: jalankan build produksi saat ini terhadap database staging dengan migrasi baru diterapkan.
- Urutan migrasi: pastikan migrasi pertama bersifat additif, dan jadwalkan perubahan destruktif (drop kolom, perketat constraint) nanti.
- Rollback: definisikan undo tercepat. Untuk blue-green, itu memindahkan kembali traffic. Untuk canary, itu mengirim 100% traffic ke versi stabil. Jika rollback membutuhkan migrasi lain, itu bukan rollback sederhana.
- Performa: ukur latensi query setelah perubahan skema, bukan hanya kebenaran data. Indeks yang hilang bisa membuat satu endpoint terasa seperti outage.
- Realita klien: identifikasi versi aplikasi mobile tertua yang masih aktif memanggil API Anda. Jika persentase berarti masih di sana, rencanakan jendela kompatibilitas lebih lama.
Skenario sanity cepat
Jika Anda menambahkan field baru seperti preferred_language, deploy perubahan database dulu sebagai nullable. Lalu kirim kode server yang membacanya jika ada tetapi tidak memerlukannya. Baru setelah sebagian besar traffic pada app ter-upgrade, jadikan field itu required atau hapus perilaku lama.
Contoh: menambah field baru tanpa memutus aplikasi mobile lama
Bayangkan Anda menambah field profil country, dan bisnis ingin field itu wajib. Itu bisa memutus di dua tempat: klien lama mungkin tidak mengirim field, dan database mungkin menolak write jika Anda menegakkan NOT NULL terlalu dini.
Pendekatan aman adalah dua perubahan terpisah: pertama tambahkan field dengan cara kompatibel mundur, lalu tegakkan "wajib" nanti setelah klien catch up.
Bagaimana dengan blue-green
Dengan blue-green, Anda deploy versi baru berdampingan dengan yang lama. Anda tetap perlu perubahan database kompatibel dengan kedua versi.
Alur aman:
- deploy migrasi (tambah
countrysebagai nullable) - deploy versi green yang menerima
countryhilang dan memakai fallback - uji alur utama pada green (signup, edit profile, checkout)
- switch traffic
Jika ada yang salah, switch kembali. Kuncinya: switch kembali hanya bekerja jika skema masih mendukung versi lama.
Bagaimana dengan canary
Dengan canary, Anda buka perilaku API baru untuk sebagian kecil (biasanya 1%–5%) dan pantau error missing-field, perubahan latensi, dan kegagalan database tak terduga.
Kejutan umum: klien mobile lama mengirim update profil tanpa country. Jika API langsung menganggap wajib, Anda akan melihat error 400. Jika database menegakkan NOT NULL, Anda mungkin melihat 500.
Urutan yang lebih aman:
- tambahkan
countrysebagai nullable (opsional dengan default aman seperti "unknown") - terima
countryyang hilang dari klien lama - backfill
countryuntuk pengguna yang ada melalui job background - tegakkan "wajib" nanti (pertama di API, lalu di database)
Setelah rilis, dokumentasikan apa yang bisa dikirim klien lama dan apa yang dijamin server. Kontrak tertulis itu mencegah pemutusan yang sama di migrasi berikutnya.
Jika Anda membangun dengan AppMaster (appmaster.io), disiplin rollout yang sama berlaku meskipun Anda bisa menghasilkan backend, web, dan aplikasi mobile native dari satu model. Gunakan platform untuk mengirim perubahan skema additif dan logika API yang toleran dulu, lalu perketat constraint hanya setelah adopsi cukup tinggi.
FAQ
Blue-green menjalankan dua lingkungan penuh dan memindahkan semua traffic sekaligus. Canary merilis versi baru ke persentase kecil dulu dan meningkatkannya berdasarkan pengamatan lalu lintas nyata.
Gunakan blue-green ketika Anda ingin cutover yang bersih dan Anda yakin versi baru kompatibel dengan skema database saat ini. Ini sangat membantu bila risiko utama ada pada kode aplikasi, bukan perilaku yang tidak terduga di produksi.
Pilih canary saat Anda perlu belajar dari lalu lintas nyata sebelum melakukan rollout penuh, misalnya ketika pola query, data edge-case, atau pekerjaan background mungkin berperilaku berbeda di produksi. Canary mengurangi blast radius, tetapi Anda harus memantau metrik dengan ketat dan siap menghentikan rollout.
Tidak. Jika perubahan skema memutus kompatibilitas (seperti menghapus atau mengganti nama kolom yang masih dipakai kode lama), baik blue-green maupun canary bisa gagal. Perbaikan yang lebih aman adalah merancang migrasi online yang mendukung versi lama dan baru bersamaan.
Pengguna mobile bisa tetap pada versi lama selama berminggu-minggu, sehingga backend Anda harus mendukung beberapa generasi klien sekaligus. Itu biasanya berarti mempertahankan kompatibilitas balik API lebih lama dan menghindari perubahan yang mengharuskan semua klien memperbarui segera.
Mulailah dengan perubahan additif yang bisa diabaikan oleh kode lama, seperti menambah kolom nullable atau tabel baru. Deploy kode yang bisa membaca kedua bentuk data dan menulis dengan cara kompatibel, lakukan backfill secara bertahap, ganti perilaku, dan baru kemudian hapus field lama atau perketat constraint.
Buat daftar apa yang dikirim dan diharapkan klien lama, lalu hindari menghapus field atau mengubah maknanya. Lebih baik menambah field opsional baru, menerima kedua bentuk request, dan menunda validasi “required” sampai adopsi cukup tinggi.
Dual-write berarti menulis data ke tempat lama dan baru selama transisi; dual-read berarti membaca field baru dengan fallback ke yang lama. Gunakan ini sementara, pantau jalur mana yang dipakai, dan rencanakan langkah pembersihan jelas ketika klien lama menghilang.
Feature flag memungkinkan Anda mendeploy kode tanpa mengaktifkan perilaku berisiko. Anda bisa memisahkan "deploy" dari "menghidupkan" fitur, menghidupkannya untuk grup kecil, dan mematikannya cepat jika terjadi lonjakan error tanpa redeploy penuh.
Menghapus atau mengganti nama kolom terlalu cepat, memaksa NOT NULL sebelum klien mengirim nilai, dan menjalankan migrasi yang mengunci tabel besar saat jam sibuk sering menyebabkan outage. Juga umum menaruh asumsi bahwa data percobaan sama dengan produksi, sehingga backfill gagal pada null atau format aneh di data nyata.


