Feature flag nedir? Üretimde blast radius kontrolü nasıl
Summary
Feature flag, kodun içinde çalışma zamanında okunan bir koşuldur ve yeni bir kod yolunu deploy yapmadan açıp kapatmanıza izin verir. SRE açısından asıl değeri, bir sürümü olaydan bir kadrana çevirmesi ve geri almayı saniyelere indirmesidir. Riski ise biriken flag borcudur: her flag bir kaldırma tarihi ve bir sahip istemelidir. Makalede dört flag türü, kendi yazılan sistemle platform arasındaki takas ve gözlemlenebilirlik kurulumu anlatılıyor.
Saat 03:12 ve checkout hata oranı az önce yüzde 4'ü aştı. Sorunu çıkaran değişiklik altı saat önce yayına girdi. Ama sürümün tamamını geri almak istemiyorsunuz, çünkü sürümde iki ilgisiz düzeltme daha var. Bu durumda feature flag nedir? Kodun içinde, çalışma zamanında okunan bir koşuldur. Bu koşul yeni kod yolunun çalışıp çalışmayacağına karar verir. Flag'i kapatırsınız, yeni yol çalışmayı bırakır ve ne build ne de deploy gerekir. Fikrin tamamı bu. Geri kalan her şey operasyon işidir.
Feature flag gerçekte nedir, ne değildir?
Feature flag bir karar noktasıdır. Kodun bir yerinde bir if vardır ve okuduğu değer binary'nin dışından gelir: bir yapılandırma servisinden, bir veritabanı satırından, bir vendor SDK'sından ya da yeniden başlatma gerektirmeden değiştirebildiğiniz bir ortam değişkeninden.
const useNewPricing = await flags.isEnabled("new-pricing-engine", {
userId: user.id,
plan: user.plan,
region: request.region,
});
return useNewPricing
? newPricingEngine.quote(cart)
: legacyPricing.quote(cart);Bu parçadan üç sonuç çıkar. Eski yol hâlâ var olmak zorundadır ve çalışmaya devam etmelidir. Basit açık-kapalı yerine daha akıllı bir şey istiyorsanız flag'in bağlama ihtiyacı vardır, yani isteği kimin yaptığını bilmesi gerekir. Ayrıca değerlendirme isteğin sıcak yolunda çalıştığı için gecikmesi ve arıza davranışı artık sizin sorumluluğunuzdadır.
İnsanlar "feature toggle" ile "feature flag" terimlerini birbirinin yerine kullanır. Kelimenin önemi yok. Önemli olan davranıştır: kodu üretime göndermekle onu kullanıma açmayı birbirinden ayırırsınız. Kod karanlıkta, yani kimse görmeden üretime girer. Kimin göreceğine ise bir insan ya da bir sistem daha sonra karar verir.
Dört tür flag ve karıştırmanın bedeli
Flag kaynaklı acıların çoğu, hepsini tek bir şeymiş gibi görmekten gelir. Martin Fowler'ın feature toggle taksonomisi flag'leri ne kadar yaşayacaklarına ve kararın ne kadar dinamik olduğuna göre ayırır. Pratikte iyi işliyor.
Release toggle'lar geçicidir. Yarım kalmış işi bir flag'in arkasına saklar, böylece her gün trunk'a birleştirebilirsiniz. Fowler'ın önerisi, bunların nadiren bir ya da iki haftadan fazla yaşaması gerektiğidir. Karar statiktir: belirli bir sürüm için her istek aynı cevabı alır.
Experiment toggle'lar farklı kullanıcıları farklı varyantlara yönlendirir. İstatistiksel anlamlılığa ulaşacak kadar, yani saatler ya da haftalar boyunca açık kalırlar, ondan uzun değil. Karar istek bazındadır.
Ops toggle'lar operasyonel davranışı yönetir: yük altında kritik olmayan bir özelliği kapatmak, yedek bir bağımlılığa geçmek ya da pahalı bir sorguyu devre dışı bırakmak gibi. İçlerinden birkaçı uzun ömürlü bir kill switch'e dönüşür. Bunların saniyeler içinde değişebilmesi gerekir, bu yüzden yeni sürüm çıkarmayı gerektiren hiçbir yöntem işe yaramaz.
Permission toggle'lar özellikleri plana ya da yetkiye göre kapılar. Yıllarca yaşayabilirler ve karar her istekte kullanıcı bazındadır.
Hata, dördüne de aynı yaşam döngüsünü vermektir. Bir permission toggle'ın sonsuza kadar bir sahibi ve bir denetim izi olmalıdır. Bir release toggle'ın ise oluşturulduğu gün bir silinme tarihi olmalıdır. Bir flag'in hangi tür olduğunu adına bakarak anlayamıyorsanız, hangilerinin güvenle kaldırılabileceğini de anlayamazsınız.
Bu ayrımı kod incelemesinde görmek mümkündür. Bir pull request'te yeni bir flag göründüğünde üç soru sorun: Bu flag hangi türde? Sahibi kim? Ne zaman silinecek? Cevap veremiyorsanız, flag'i birleştirmeden önce bu bilgileri ekleyin. Bu yirmi dakikalık bir tartışma gibi görünebilir, ama altı ay sonra bir flag'in neden hâlâ orada olduğunu sorgulamaktan çok daha ucuzdur. Ekip olarak şöyle bir kural da işe yarar: adında tür ve sahip bilgisi olmayan flag'ler kod incelemesinden geçemez.

SRE neden önemser: flag bir blast radius kontrolüdür
Bir platform ekibi için ilginç olan özellik A/B testi değildir. Flag, bir sürümü bir olaydan bir kadrana çevirir.
Flag olmadan bir deploy, değişikliği tüm trafiğe aynı anda açar. Tek geri dönüş başka bir deploy'dur ve bu, pipeline'ınızın süresi kadar, bir de insanın emin olması için geçen süre kadar sürer. Flag ile değişikliği yüzde 1 kullanıcıya açabilir, hata oranını ve p99 değerini izleyip ardından yüzde 5, 25, 50'ye geçebilirsiniz. Blast radius, seçtiğiniz yüzdedir ve geri dönüş, saniyeler içinde yayılan bir yapılandırma değişikliğidir.
Bu, yatırım yaptığınız araçların çoğundan daha fazla mean time to recover değerinizi değiştirir. Post-mortem sorusu "geri almak neden 40 dakika sürdü?" olmaktan çıkar ve "bunu neden bir flag'in arkasına koymadık?" sorusuna dönüşür.
Ama rollout kadranının bir tuzağı var. Sinyalleri birinin izlemesi ve kadranı çevirmesi gerekir. 03:12'de o kişi yorgundur. Flag sisteminin işe yarayan hali, kadranı bir service level objective'e bağlar. Hata oranı belirlenen bir hata bütçesi payını tüketirse rollout, bir insan devreye girmeden durur ve geri alınır. Çoğu ekip bunu, alerting aracından flag API'sine giden bir webhook ile elle kurar. Birkaç yüz satır tutar ve ilk gece tetiklendiğinde kendini öder.
Bu noktada bir ayrıntı önemlidir: otomatik geri alma, her zaman otomatik ileri almadan daha güvenli bir varsayılandır. Eşiği aşan bir sinyal rollout'u durdurmalı ve bir insanı uyarmalıdır. Kendiliğinden yüzde 100'e çıkan bir sistem ise sinyal bozuksa bir olayı daha hızlı büyütür. Ölçü, hem tetikleyici hem de geri dönüş için önceden yazılmış olmalıdır: hangi metrik, hangi pencere ve hangi eşik.
Faturası gelir: flag borcu ve Knight Capital dersi
Eklediğiniz her flag, teoride o koddaki yol sayısını ikiye katlar. Pratikte birkaç kombinasyonu test edersiniz ve gerisine güvenirsiniz. Fowler, flag'leri taşıma maliyeti olan bir envanter gibi görmenizi önerir. Flag oluşturulduğunda backlog'a bir kaldırma görevi ekleyin, onlara son kullanma tarihi verin ve en katı ekiplerde süresi dolmuş bir flag hâlâ koddaysa build'i başarısız kılın.
Bu dersin en pahalı hali Knight Capital'dir. 1 Ağustos 2012'de yeni bir deploy, bir zamanlar emekli edilmiş bir özelliği kontrol etmiş eski bir flag'i yeniden kullandı. Bir sunucu deploy'u kaçırdı ve eski kodu çalıştırmaya devam etti. Piyasa açılışından sonraki ilk 45 dakikada firmanın router'ı, 212 müşteri emrini doldurmaya çalışırken piyasaya 4 milyondan fazla emir gönderdi. SEC'in Knight Capital aleyhine verdiği karar bu olayı kaydeder. Fowler'ın makalesi, yaklaşık 460 milyon $ tutarındaki kaybı, yönetilmeyen flag'ler hakkında bir uyarı olarak anar.
Flag tek başına suçlu değildi. Manuel deploy, kill switch'in olmaması ve yavaş tespit de katkı yaptı. Ama ölü bir flag adını yeniden kullanmak, her platform ekibinin duvarına asması gereken ayrıntıdır. Bir flag'i asla yeniden kullanmayın. Eskisini silin, yenisini oluşturun ve kaldırmayı birinci sınıf bir adım yapın.

Kendiniz mi yazarsınız, bir flag platformu mu alırsınız?
Kendi yazdığınız flag sistemi bir yapılandırma dosyası ve bir boolean ile başlar. Tek bir servis üzerindeki ilk birkaç release toggle için bu yeterlidir. Kullanıcı başına sabit kalan yüzdelik rollout'lara, segment bazlı hedefleme kurallarına, kimin neyi değiştirdiğini gösteren bir denetim kaydına ve yapılandırma deposunu bir thundering herd'e sokmadan saniyeler içinde her instance'a ulaşan bir flag değişikliğine ihtiyaç duyduğunuzda yetersiz kalır.
O noktada platformları ölçülebilir kriterlerle karşılaştırırsınız: SDK değerlendirme gecikmesi (yerel değerlendirme mi, ağ çağrısı mı), güncellemeler için streaming mi polling mi, hedefleme kuralı granülerliği, çoklu ortam desteği ve fiyatlandırma ölçeğinin trafiğinizle nasıl büyüdüğü.
Fiyatlandırma ölçüleri, özellik listelerinden daha çok ayrışır.
LaunchDarkly, kategorinin referans uygulamasıdır: olgun hedefleme, korumalı sürümler ve derin bir entegrasyon yüzeyi. Kullanım bazlı planları servis bağlantısı başına ve bin aylık aktif istemci tarafı kullanıcı başına faturalandırır. Bu yüzden geniş bir anonim kitleye sahip bir tüketici uygulaması, yalnızca backend'de çalışan bir ekibin görmeyeceği şekillerde faturanın oynadığını görebilir. Olumlu tarafı gerçek: kurumsal ölçekte yönetişim ve denetim istiyorsanız, bu ürün bunu sertleştirmek için en uzun süreye sahip olmuştur.
Statsig, flag'leri deneyler ve ürün analitiğiyle paketler ve olaylara göre faturalandırır. Bu, flag'leri çoğunlukla bir deney yüzeyi olarak gören ekiplere uyar. Kullanım alanınız ağırlıklı olarak ops toggle'ları ve kill switch'ler ise okumayabileceğiniz bir analitik için ödeme yapıyorsunuz demektir. Ayrıca satıcı Eylül 2025'ten bu yana iki kez sahip değiştirdi. Bu, tedarikçi risk değerlendirmenizde bir satır hak ediyor.
Hangisini seçerseniz seçin, imzalamadan önce arıza davranışını test edin. Staging ortamında SDK'nın ağ erişimini engelleyin ve uygulamanın ne yaptığına bakın. İyi bir SDK, son bilinen flag değerlerini önbellekten sunar ve yüksek sesle loglar. Kötü bir SDK ise istek yolunu bloklar.
Gözlemlenebilirlik, flag sisteminin yarısıdır
Telemetrisi olmayan bir flag bir tahmindir. Asgari yararlı kurulum, flag durumunu isteğin her trace'ine ve log satırına iliştirir. Böylece bir hata sıçraması göründüğünde flag varyantına göre gruplayıp yeni yolun sebep olup olmadığını görebilirsiniz.
Datadog ve benzeri hepsi bir arada platformlar, SDK'nız span'leri etiketlediğinde varyant bazında dökümü kolaylaştırır. Ancak flag anahtarı, varyant ve kullanıcı segmenti gibi yüksek kardinaliteli etiketler eklediğinizde host ve sinyal başına faturalandırma hızla büyür. Hangi boyutları etiketleyeceğinizi bilinçli seçin.
Prometheus ve OpenTelemetry zaten çalıştırıyorsanız Grafana daha ucuz yoldur. Flag farkında dashboard'ları kendiniz kurarsınız. Bu mühendislik zamanına mal olur, ama yaydığınız etiketler üzerinde tam kontrol verir. 50 ila 500 mühendisi ve bir platform grubu olan bir ekip için bu takas çoğu zaman doğrudur.
Uyarı kurallarının da flag'i bilmesi gerekir. Yüzde 5'lik varyantta p99 değeri iki katına çıktığında tetiklenen bir uyarı, sayfalanan kişiye hangi varyantın sorumlu olduğunu ilk dakikada söyler. Aksi halde ekip, sorunu aramak için dashboard'lar arasında gidip gelir. Gece 03:00'te en çok zaman kaybettiğiniz yer tam burasıdır.

İlk flag'iniz için kısa bir runbook
Flag'leri hiç olmayan bir ekibe tanıtıyorsanız, ilk rollout'u sıkıcı tutun.
Açık bir başarı metriği olan tek bir değişiklik seçin, örneğin checkout hata oranı ya da tek bir endpoint'in p99 gecikmesi.
Flag'i tipi ve sahibiyle adlandırın, örneğin
release.checkout.new-tax-calc.owner-payments.Kaldırma görevini şimdi yazın ve en fazla iki hafta sonrasına bir son kullanma tarihi iliştirin.
Yüzde 1 ile açın, bir tam trafik döngüsü boyunca bekleyin, sonra basamak basamak artırın. Geri alacağınız eşiği önceden tanımlayın.
Geri almayı tek bir komut ya da tek bir düğme yapın ve gece ihtiyaç duymadan önce bir kez staging'de prova edin.
Yüzde 100 birkaç gün sürdükten sonra flag'i ve eski kod yolunu aynı değişiklikte silin.
Atlanması en kolay adım 6. Bunu atlayan ekipler birkaç yüz flag'le, yarısının ne yaptığını bilen kimse olmadan ve depoda Knight şeklinde bir riskle kalır.
Son olay bir flag'in arkasında olsaydı nasıl görünürdü?
Ekibinizin yazdığı son üretim olayını düşünün ve üç soru sorun. Değişiklik karanlıkta yayına girebilir miydi? Biri bir dakikadan kısa sürede, deploy yapmadan onu devre dışı bırakabilir miydi? Bir uyarı size hangi varyantın hata verdiğini söyler miydi?
Üçüne de cevap hayırsa, ilk flag adayınız ve bugün bir geri almanın size ne kadara mal olduğuna dair ilk dürüst tahmininiz elinizdedir. Post-mortem ne diyecekse onu diyecektir. Daha iyi soru şudur: pager çaldığında bunun ne kadarını daha küçük hale getirebilirdiniz?