Einführung von Feature Flags für sicherere Deployments
Kontext
Unser Deployment-Prozess war alles oder nichts. Neue Funktionen gingen sofort mit dem Deployment für alle Nutzer:innen live, was Rollbacks störend machte und unsere Möglichkeit einschränkte, in Produktion zu testen.
Entscheidung
Einführung eines Feature-Flag-Systems mit LaunchDarkly für schrittweise Rollouts und sofortige Kill-Switches
Betrachtete Alternativen
Eigenes Feature-Flag-System entwickeln
- Volle Kontrolle über die Implementierung
- Keine externe Abhängigkeit
- Keine Lizenzkosten pro Nutzer
- Erheblicher Entwicklungsaufwand
- Targeting, Analytics und UI müssen selbst gebaut werden
- Wartungsaufwand für das Team
LaunchDarkly verwenden
- Bewährt im großen Maßstab
- Umfangreiche Targeting-Möglichkeiten
- Integrierte Analytics und Experimentierfunktionen
- Gute SDK-Unterstützung
- Monatliche Kosten (~500 $/Monat bei unserer Größenordnung)
- Externe Abhängigkeit
- Daten verlassen unsere Infrastruktur
Umgebungsvariablen verwenden
- Einfach umzusetzen
- Keine externen Abhängigkeiten
- Erfordert erneutes Deployment für Änderungen
- Keine Möglichkeit für schrittweise Rollouts
- Kein Nutzer-Targeting
Begründung
Die Kosten von LaunchDarkly sind durch die eingesparte Entwicklungszeit und die Risikoreduzierung durch schrittweise Rollouts gerechtfertigt. Ein vergleichbares System selbst zu entwickeln würde Monate dauern und laufende Wartung erfordern. Die Möglichkeit, problematische Funktionen sofort ohne erneutes Deployment zu deaktivieren, ist von unschätzbarem Wert.
Das Problem
Unsere Deployment-Angst war groß:
- Jedes Deployment war ein potenzieller Vorfall
- Rollbacks erforderten ein vollständiges erneutes Deployment (5–10 Minuten)
- Keine Möglichkeit, Funktionen mit einer Teilmenge von Nutzer:innen zu testen
- Das Produktteam konnte keine A/B-Tests durchführen
Feature-Flag-Strategie
Wir haben Muster für die Nutzung von Flags festgelegt:
Release Flags: Temporäre Flags für neue Funktionen
if (flags.isEnabled('new-checkout-flow', user)) {
return newCheckoutFlow();
}
return legacyCheckoutFlow();
Ops Flags: Dauerhafte Flags für operative Kontrolle
if (flags.isEnabled('enable-cache', { service: 'api' })) {
return cachedResponse();
}
Experiment Flags: Für A/B-Tests
const variant = flags.getVariant('pricing-test', user);
return pricingPages[variant];
Rollout-Prozess
Neue Funktionen folgen nun diesem Prozess:
- Deployment mit deaktiviertem Flag (0 %)
- Aktivierung für interne Nutzer:innen (Dogfooding)
- Aktivierung für 1 % der Nutzer:innen, Beobachtung
- Schrittweise Erhöhung: 5 % → 25 % → 50 % → 100 %
- Entfernung des Flags, sobald die Funktion stabil ist
Ergebnisse
- Deployment-Häufigkeit: 3-fache Zunahme (weniger Angst)
- Wiederherstellungszeit bei Vorfällen: 90 % Reduzierung (sofortiger Kill-Switch)
- Durchgeführte A/B-Tests: 12 im ersten Quartal (zuvor 0)
- Vertrauen der Entwickler:innen: deutlich verbessert
Die Kosten von 500 $/Monat haben sich durch reduzierte Vorfallauswirkungen und schnellere Iteration vielfach amortisiert.
Erkenntnisse
- Flag-Hygiene ist wichtig: Wir planen regelmäßiges Aufräumen der Flags, um technische Schulden zu vermeiden
- Standardmäßig deaktiviert: Neue Flags sollten standardmäßig deaktiviert sein
- Zweck der Flags dokumentieren: Jedes Flag braucht einen Owner und ein Ablaufdatum