Feature Flag Bukan Satu-Satunya Kontrol Rilis yang Anda Butuhkan

Sebuah tim yang pernah saya dampingi menghabiskan tiga bulan membangun alur checkout baru. Kode sudah selesai, teruji di staging, dan digabungkan ke branch utama di belakang sebuah feature flag. Ketika mereka akhirnya mengaktifkan flag untuk 5% pengguna, penyedia pembayaran mengembalikan error yang tidak pernah mereka lihat di staging. Flag tersebut memungkinkan mereka mematikannya dalam hitungan detik. Namun pertanyaan sebenarnya adalah: haruskah kode itu berada di produksi sama sekali?

Feature flag memang ampuh. Mereka memungkinkan Anda men-deploy kode yang belum aktif, menguji di produksi dengan lalu lintas nyata, dan meluncurkan perubahan secara bertahap. Tapi feature flag bukan solusi universal. Terkadang branch lebih baik. Terkadang environment terpisah lebih masuk akal. Dan terkadang Anda membutuhkan ketiganya bekerja bersama.

Pertanyaan pertama yang harus dijawab adalah: apa yang sebenarnya ingin Anda capai dengan menunda atau membatasi akses ke fitur baru?

Kapan Menggunakan Branch

Branch ada untuk mengisolasi pekerjaan yang sedang berlangsung. Jika sebuah fitur belum selesai dan tidak bisa berjalan tanpa merusak aplikasi, simpan di branch. Kode tidak masuk ke branch utama sama sekali. Tidak ada yang tidak sengaja men-deploy-nya. Tidak ada yang harus mengingat bahwa sebuah flag ada.

Ini adalah bentuk kontrol yang paling sederhana. Cocok untuk fitur yang masih dalam pengembangan, terutama ketika beberapa pengembang mengerjakan bagian yang berbeda. Branch utama tetap bersih. Tim hanya menggabungkan kode ketika fitur sudah selesai dan telah di-review.

Namun branch memiliki keterbatasan. Begitu kode digabungkan, Anda kehilangan kemampuan untuk mengontrol aktivasi fitur. Fitur tersebut ada di branch utama atau tidak. Tidak ada jalan tengah. Di sinilah feature flag berperan.

Kapan Menggunakan Feature Flag

Feature flag mengontrol perilaku setelah kode digabungkan. Kode sudah di branch utama, sudah di-deploy ke produksi, tetapi belum aktif untuk semua pengguna. Anda bisa mengaktifkannya untuk persentase kecil, untuk penguji internal, atau untuk kondisi tertentu.

Ini berguna ketika fitur sudah fungsional tetapi Anda belum siap mengeksposnya ke semua orang. Mungkin Anda ingin memvalidasi stabilitas di bawah lalu lintas nyata. Mungkin Anda perlu memantau tingkat error sebelum peluncuran penuh. Mungkin Anda ingin melakukan peningkatan bertahap selama beberapa hari.

Feature flag juga membantu rollback. Jika ada yang salah, Anda mematikan flag alih-alih mengembalikan deployment. Itu lebih cepat dan lebih aman daripada mengembalikan kode, terutama ketika deployment mencakup migrasi database atau perubahan ireversibel lainnya.

Tapi feature flag tidak gratis. Mereka menambah kompleksitas pada basis kode. Setiap flag adalah cabang if-else yang harus dipelihara, diuji, dan pada akhirnya dihapus. Terlalu banyak flag yang bertahan terlalu lama menciptakan utang teknis. Tim yang mengumpulkan puluhan flag basi berakhir dengan kode yang sulit dibaca dan lebih sulit di-debug.

Kapan Menggunakan Environment Terpisah

Environment staging memberi Anda tempat untuk menguji sebelum produksi. Ia terisolasi dari pengguna nyata. Anda bisa menjalankan pengujian integrasi, QA manual, dan pengujian eksplorasi tanpa memengaruhi siapa pun.

Masalahnya adalah staging tidak pernah identik dengan produksi. Pola lalu lintas berbeda. Volume data lebih kecil. Perilaku pengguna nyata tidak bisa direplikasi. Beberapa masalah hanya muncul di bawah beban produksi, dengan data produksi, atau dengan konfigurasi infrastruktur yang tidak dimiliki staging.

Itulah mengapa feature flag dan environment saling melengkapi. Gunakan staging untuk pengujian awal. Gunakan feature flag untuk validasi produksi. Keduanya bukan pengganti. Mereka adalah dua lapis keamanan.

Fitur besar yang mengubah alur inti—seperti mengganti sistem pembayaran atau mendesain ulang halaman login—sebaiknya melewati staging terlebih dahulu. Setelah lulus di sana, Anda bisa men-deploy-nya di belakang flag di produksi dan secara bertahap meningkatkan eksposur.

Menggabungkan Branch, Environment, dan Flag

Dalam praktiknya, banyak tim menggunakan ketiganya bersama-sama. Berikut pola yang umum:

  1. Kerjakan fitur besar di branch terpisah.
  2. Gabungkan branch ke branch utama dengan flag dalam keadaan mati.
  3. Deploy ke staging, uji fitur dengan mengaktifkan flag di staging.
  4. Deploy ke produksi dengan flag masih mati.
  5. Aktifkan flag untuk pengguna internal atau persentase kecil.
  6. Tingkatkan persentase secara bertahap berdasarkan pemantauan.
  7. Hapus flag setelah fitur sepenuhnya diluncurkan dan stabil.

Pola ini umum di tim yang menerapkan trunk-based development. Branch utama selalu bisa di-deploy. Fitur besar dipecah menjadi bagian-bagian kecil, masing-masing dikendalikan oleh flag. Tim sering menggabungkan kode, sering men-deploy, dan menggunakan flag untuk mengontrol apa yang dilihat pengguna.

Kapan Feature Flag Adalah Pilihan yang Salah

Feature flag tidak selalu menjadi alat terbaik. Pertimbangkan situasi berikut:

  • Fitur tidak bisa dijalankan. Jika kode tidak bisa dikompilasi, gagal dalam pengujian, atau crash saat startup, jangan digabungkan. Simpan di branch sampai berfungsi.
  • Perubahan terlalu besar untuk dikendalikan dengan satu flag. Flag yang men-toggle seluruh subsistem sulit diuji dan berisiko untuk diaktifkan. Pecah fitur menjadi bagian-bagian yang lebih kecil, masing-masing dengan flag sendiri, atau gunakan environment untuk validasi awal.
  • Tim menggunakan flag untuk menghindari keputusan. Jika sebuah flag ada karena tidak ada yang mau memutuskan apakah fitur sudah siap, itu adalah masalah proses, bukan masalah alat. Flag seharusnya mempercepat umpan balik, bukan menunda percakapan sulit.
  • Flag akan bertahan selamanya. Beberapa tim menyimpan flag tanpa batas waktu karena menghapusnya terasa berisiko. Itu pertanda bahwa flag dirancang dengan buruk atau tim kurang percaya diri dengan proses rilis mereka. Setiap flag harus memiliki tanggal penghapusan yang direncanakan.

Daftar Periksa Praktis untuk Memilih Kontrol Rilis

Situasi Kontrol yang Direkomendasikan
Fitur belum selesai dan tidak bisa berjalan Branch
Fitur sudah selesai tetapi perlu validasi produksi Feature flag
Fitur perlu pengujian terisolasi sebelum produksi Environment staging
Fitur besar dan mengubah perilaku inti Staging dulu, lalu flag
Tim menerapkan trunk-based development Kombinasi branch + flag
Fitur kecil dan berisiko rendah Feature flag atau deploy langsung

Ini bukan tabel yang kaku. Setiap tim memiliki toleransi risiko dan infrastruktur yang berbeda. Gunakan sebagai titik awal diskusi, bukan sebagai buku aturan.

Diagram pohon keputusan di bawah merangkum pertanyaan kunci dan kontrol yang direkomendasikan.

flowchart TD A[Apakah fitur sudah selesai?] -->|Tidak| B[Gunakan branch] A -->|Ya| C[Apakah perlu peluncuran bertahap?] C -->|Tidak| D[Apakah perlu pengujian terisolasi?] C -->|Ya| E[Gunakan feature flag] D -->|Tidak| F[Deploy langsung atau flag kecil] D -->|Ya| G[Gunakan environment staging] E --> H[Perlu juga diuji di staging?] H -->|Ya| I[Environment + flag] H -->|Tidak| J[Hanya flag] G --> K[Juga perlu peluncuran bertahap?] K -->|Ya| L[Environment + flag] K -->|Tidak| M[Hanya environment]

Tujuan Sebenarnya

Feature flag, branch, dan environment adalah alat. Tujuannya bukan menggunakan semuanya. Tujuannya adalah mengirimkan perangkat lunak dengan aman dan mendapatkan umpan balik dengan cepat.

Strategi rilis yang baik memungkinkan Anda men-deploy sering, menguji di produksi dengan risiko terkendali, dan mematikan sesuatu ketika ada yang salah. Ia tidak membiarkan Anda menunda keputusan atau mengakumulasi fitur setengah jadi di produksi.

Mulailah dengan memahami apa yang ingin Anda kendalikan. Lalu pilih alat yang sesuai. Dan ketika Anda menggunakan feature flag, ingatlah untuk menghapusnya. Flag terbaik adalah flag yang sudah tidak ada lagi.