Feature Flag: Kapan Berguna, Kapan Jadi Beban
Di dunia sistem informasi klinik atau rumah sakit, rilis fitur baru itu berisiko tinggi. Modul rekam medis atau billing yang dipakai puluhan user setiap menit tidak bisa begitu saja "deploy dan berdoa". Di titik inilah feature flag jadi salah satu alat paling berguna yang saya andalkan — tapi juga salah satu yang paling mudah disalahgunakan sampai akhirnya membebani codebase itu sendiri.
Kenapa Feature Flag Relevan
Feature flag pada dasarnya adalah saklar di kode yang menentukan apakah sebuah fitur aktif atau tidak, tanpa perlu deploy ulang. Manfaat utamanya ada tiga: rilis bertahap (misalnya hanya aktif untuk satu klinik dulu sebelum ke semua fasilitas), kemampuan mematikan fitur bermasalah dengan cepat tanpa rollback kode, dan memisahkan "deploy" dari "release" — kode bisa masuk production lebih dulu, baru diaktifkan belakangan saat siap.
Di Laravel, ini bisa sesederhana kolom konfigurasi di database atau memakai paket seperti Laravel Pennant. Contoh sederhana:
if (Feature::active('billing-v2')) {
return app(BillingV2Service::class)->process($invoice);
}
return app(BillingService::class)->process($invoice);
Pola ini terlihat sepele, tapi efeknya besar: tim bisa merilis modul billing baru ke satu klinik percobaan, memantau perilakunya, lalu memperluas cakupan secara bertahap tanpa harus deploy ulang setiap kali.
Kapan Feature Flag Jadi Beban
Masalah muncul ketika flag dianggap sebagai solusi permanen, bukan sementara. Saya sering melihat (dan pernah membuat sendiri) kondisi if-else bertumpuk untuk flag yang sebenarnya sudah aktif penuh di semua environment selama berbulan-bulan, tapi tidak pernah dihapus dari kode. Akibatnya:
- Kompleksitas cyclomatic meningkat — satu fungsi bisa punya banyak jalur eksekusi yang jarang semuanya diuji.
- Kombinasi flag yang saling silang jadi sulit ditelusuri; flag A aktif tapi flag B mati bisa menghasilkan state yang tidak pernah direncanakan.
- Developer baru bingung mana kode "yang sebenarnya jalan" dan mana sisa eksperimen lama.
Feature flag yang menumpuk seperti ini biasa disebut sebagai bentuk "flag debt" — utang teknis yang bentuknya bukan bug, tapi kompleksitas yang tidak perlu.
Pola Praktis Supaya Flag Tidak Menumpuk
Yang membantu saya menjaga disiplin ini adalah memperlakukan setiap flag sebagai item dengan siklus hidup, bukan konfigurasi permanen:
- Beri tanggal kedaluwarsa saat membuat flag. Setiap flag baru dicatat dengan target, misalnya "harus dihapus beberapa minggu setelah rollout penuh". Ini bisa berupa komentar di kode, tiket, atau catatan di tool flag-nya sendiri.
- Bedakan jenis flag. Flag untuk rilis bertahap (release flag) sifatnya sementara dan wajib dibersihkan. Flag untuk kill-switch operasional (misalnya mematikan integrasi eksternal saat down) atau untuk pengaturan per-tenant memang boleh permanen — jangan disamaratakan perlakuannya.
- Jadikan pembersihan bagian dari definition of done. Tiket fitur baru dianggap belum selesai kalau flag-nya belum dihapus setelah rollout penuh stabil, bukan cuma "fitur sudah jalan di production".
- Batasi jumlah flag aktif bersamaan. Kalau daftar flag aktif sudah panjang dan sebagian besar sudah menyala penuh tanpa alasan jelas, itu sinyal untuk sesi "flag cleanup" terjadwal, bukan menunggu sampai menumpuk lebih jauh.
Sebagai ilustrasi, tim dengan disiplin ini biasanya menjaga jumlah flag aktif tetap kecil — misalnya di bawah selusin flag rilis yang benar-benar "hidup" pada satu waktu — dibanding tim tanpa disiplin yang bisa mengakumulasi puluhan flag mati yang tidak pernah dibersihkan.
Takeaway
Feature flag adalah alat rilis, bukan arsitektur permanen. Nilainya justru ada pada kesementaraannya: begitu sebuah fitur stabil dan sudah aktif penuh, flag-nya seharusnya hilang dari kode, bukan menjadi lapisan percabangan yang terus dibawa selamanya. Kalau tim Anda mulai memakai flag secara rutin, tetapkan aturan siklus hidupnya sejak awal — itu jauh lebih murah daripada membersihkannya belakangan.