Wenn Feature Flags zur technischen Schuld werden
Du hast eine neue Funktion mit einem Feature Flag ausgerollt. Es hat funktioniert. Die Nutzer haben es angenommen. Das Flag blieb für alle aktiv. Monate vergingen. Jetzt ist dieses Flag immer noch im Code, neben drei anderen Flags aus dem letzten Quartal, zwei von vor sechs Monaten und einem, von dem niemand mehr weiß, was es steuert.
Das ist keine Seltenheit. Viele Teams beginnen mit guten Vorsätzen mit Feature Flags: sicherere Releases, schrittweise Rollouts, Kill Switches für Notfälle. Aber Flags, die nie entfernt werden, verwandeln sich langsam in eine andere Art von Problem. Sie sind kein Release-Control-Tool mehr, sondern werden zur technischen Schuld, die alle ausbremst.
Die wahren Kosten verlassener Flags
Jedes Flag, das du im Code zurücklässt, fügt eine Entscheidungsstelle hinzu. Wenn ein Entwickler eine Funktion liest, muss er fragen: Wird dieser Zweig noch genutzt? Ist der andere sicher zu entfernen? Kann ich den alten Codepfad löschen, oder wird er von irgendeinem Nutzer noch getroffen?
Bei ein oder zwei Flags ist das beherrschbar. Bei Dutzenden wird das Lesen von Code zum Ratespiel. Du endest mit If-Else-Blöcken, bei denen niemand sicher ist, welcher Pfad live ist. Der Code, der einmal klar war, verwandelt sich in ein Labyrinth aus bedingter Logik, das niemand anzufassen wagt.
Es gibt auch Laufzeitkosten. Jedes Mal, wenn die Anwendung läuft, wertet sie jedes Flag aus. Eine einzelne Flag-Prüfung ist billig. Hunderte Flag-Prüfungen in heißen Codepfaden summieren sich. Die CPU-Zyklen, die für die Auswertung von Flags aufgewendet werden, die immer denselben Wert zurückgeben, sind verschwendet. Der Speicher, der zum Speichern von Flag-Konfigurationen verwendet wird, die sich nie ändern, ist verschwendet. Mit der Zeit wird dieser Overhead messbar, besonders in Diensten mit hohem Datenverkehr.
Jedes Flag braucht einen Lebenszyklus
Die Lösung ist nicht, auf Feature Flags zu verzichten. Die Lösung ist, jedes Flag als etwas zu behandeln, das irgendwann entfernt werden muss. Ein Feature Flag sollte von seiner Erstellung an einen klaren Lebenszyklus haben:
Das folgende Diagramm zeigt den vorgesehenen Lebenszyklus eines Feature Flags und was passiert, wenn die Entfernung übersprungen wird:
- Das Flag wird hinzugefügt, wenn die Arbeit an einer neuen Funktion beginnt.
- Es wird für interne Tests aktiviert.
- Es wird schrittweise für eine Teilmenge der Nutzer ausgerollt.
- Es wird für alle Nutzer aktiviert.
- Die Funktion wird als stabil in der Produktion verifiziert.
- Das Flag wird entfernt.
Schritt sechs ist der, den die meisten Teams überspringen. Die Funktion funktioniert. Jeder nutzt sie. Das Flag ist immer noch an, also warum die Mühe, es zu entfernen? Weil jeder Tag, an dem das Flag bleibt, Reibung erzeugt. Der Code ist schwerer zu lesen. Die nächste Änderung dauert länger. Das Risiko, einen Fehler einzuführen, steigt, weil niemand sicher ist, welche Codepfade tatsächlich aktiv sind.
Wann ein Flag entfernt werden sollte
Der richtige Zeitpunkt, ein Flag zu entfernen, ist, sobald die von ihm gesteuerte Funktion stabil und vollständig ausgerollt ist. Einige Teams legen eine harte Regel fest: Entferne das Flag innerhalb von ein oder zwei Sprints, nachdem die Funktion 100 % der Nutzer erreicht hat. Andere verwenden automatisierte Erinnerungen, die jedes Konfigurations-Flag markieren, das über einen bestimmten Zeitraum aktiv war.
Ein Flag zu entfernen bedeutet nicht nur, die bedingte Prüfung zu löschen. Du musst auch den alten Code bereinigen, den das Flag geschützt hat. Wenn die neue Funktion eine alte ersetzt hat, lösche den alten Codepfad vollständig. Hinterlasse keinen toten Code. Toter Code ist nicht harmlos. Er verwirrt Entwickler, verschwendet Build-Zeit und kann subtile Fehler verursachen, wenn jemand ihn später ändert, in der Annahme, er sei noch in Gebrauch.
Auf der Konfigurationsseite entferne das Flag auch aus deinem Flag-Management-System. Ein Flag, das aus dem Code gelöscht, aber in einem Dashboard oder einer Konfigurationsdatei noch sichtbar ist, wird Verwirrung stiften. Irgendwann wird jemand fragen, ob dieses Flag noch benötigt wird, und niemand wird eine klare Antwort haben.
Mach die Entfernung zum Teil des Prozesses
Der effektivste Weg, um zu verhindern, dass sich Flags anhäufen, ist, bei der Erstellung eines Flags einen Entfernungsplan zu verlangen. Wenn ein Entwickler einen Pull Request öffnet, der ein neues Feature Flag hinzufügt, sollte der PR einen Hinweis enthalten, wann und wie das Flag entfernt wird. Dies kann ein Kommentar im Code, eine Aufgabe in deinem Projektmanagement-Tool oder ein automatisiertes Ablaufdatum im Flag-System selbst sein.
Einige Teams gehen noch weiter und erzwingen den Flag-Ablauf programmatisch. Das Flag-System lehnt jedes neue Flag ab, das kein obligatorisches Ablaufdatum enthält. Wenn das Datum überschritten ist, sendet das System eine Benachrichtigung oder deaktiviert das Flag sogar automatisch. Dies zwingt das Team, das Flag entweder zu entfernen oder seine Lebensdauer mit einer Begründung explizit zu verlängern.
Das klingt vielleicht nach Overhead für ein kleines Team, das eine Funktion pro Monat ausliefert. Aber das Muster skaliert. Sobald mehrere Teams parallel mehrere Funktionen ausliefern, wird manuelles Flag-Management nicht mehr tragbar. Die Disziplin, die du früh aufbaust, wird dich später vor einer schmerzhaften Bereinigung bewahren.
Eine praktische Checkliste für die Flag-Bereinigung
Wenn du heute mit der Bereinigung von Flags beginnen möchtest, hier ist ein einfacher Prozess:
- Identifiziere alle Flags, die sich derzeit in deiner Codebasis und deinem Konfigurationssystem befinden.
- Bestimme für jedes Flag, ob die von ihm gesteuerte Funktion vollständig ausgerollt und stabil ist.
- Wenn die Funktion stabil ist, entferne das Flag aus dem Code und lösche den alten Codepfad.
- Entferne das Flag aus deiner Konfiguration oder deinem Flag-Management-System.
- Aktualisiere alle Dokumentationen oder Runbooks, die das Flag referenzieren.
- Füge für jedes neue Flag einen Entfernungsplan in den Pull Request ein, der es einführt.
Dies ist keine einmalige Übung. Mach es zu einer regelmäßigen Praxis. Einige Teams widmen einen Sprint pro Quartal der Flag-Bereinigung. Andere fügen es ihrer Definition of Done für jede Funktion hinzu. Finde einen Rhythmus, der für dein Team funktioniert, und halte dich daran.
Das Fazit
Feature Flags sind ein mächtiges Werkzeug, um Releases zu steuern und Risiken zu reduzieren. Aber sie sind nicht kostenlos. Jedes Flag, das du über seine Nutzungsdauer hinaus behältst, erhöht die Komplexität, verlangsamt die Entwicklung und erhöht die Wahrscheinlichkeit von Fehlern. Das Ziel ist nicht, Flags zu vermeiden. Das Ziel ist, sie mit Disziplin zu nutzen und zu entfernen, wenn sie ihren Zweck erfüllt haben.
Wenn du Flags sich anhäufen lässt, hören sie auf, ein Release-Control-Mechanismus zu sein, und werden zu einer Last, die dein Team jeden Tag trägt. Räum sie auf. Dein zukünftiges Ich und der Entwickler, der nächsten Monat deinen Code lesen muss, werden es dir danken.