= Rollout, feature flag, experiment, operational toggle Different use cases for backend, frontend and mobile <<< == "Feature flags" tend to come up when talking about continuous deployment <<< [.lead] CI: continuous integration [.lead] CD: continuous delivery [.lead] CD: continuous deployment <<< == Types . rollout . feature flag . experiment . operational toggle // {favicon.svg} <<< == Rollout === For *rolling out* a new version of software Short-lived using percentages // FIXME: links * a new deployment of kubernetes * new APK released to the Play Store <<< == Feature flag === For turning a feature *on* or *off* Medium-lived using allow list, A/B test, percentage, app version, etc. * :new-chargeback-flow * :new-debit-card-activation-screen <<< == Experiment === For analysing behaviour Medium-lived using allow list and A/B test * :debit-withdrawal-test <<< == Operational toggle === For disabling features in #crash-like situations Long-lived using percentage * :bank-barcode-payment * :savings-bank-barcode-query-provider <<< [.lead] We know know about the types == But they have different relevance for backend, frontend and mobile <<< == backend . rollout: k8s blue/green, canary and [.line-through]#common-rollout# common-xp . feature flag: [.line-through]#common-rollout# common-xp and datasets . experiment: common-xp . operational toggle: [.line-through]#common-rollout# common-xp <<< == frontend . rollout: CDN and page refreshes . feature flag: percentages and maybe IPs (no :customer/id on the website) . experiment: via dynamic backend control . operational toggle: via dynamic backend control <<< == backend . rollout: app stores . feature flag: via dynamic backend control . experiment: via dynamic backend control . operational toggle: via dynamic backend control <<< [.lead] Key differentiator is == how much *control* we have over the environment <<< == backend === full control // FIXME: emoji // 🎉 <<< == frontend === partial control We choose when to make a new version available <<< == mobile === very limited control * app stores can restrict updates (worse for iOS) * customers still have to download new versions <<< == Costs * more complex code * compatibility with old app versions * nesting is exponential <<< == Benefits * dynamicity <<< == weighting costs × benefits === The less control we have, the more we value dynamicity <<< == weighting costs × benefits * backend: sometimes worth the cost * frontend: almost always worth the cost * mobile: *always* worth the cost <<< == Best practices <<< == dynamic content > feature flag Always true for mobile, almost always for frontend <<< == Use :include-list for named groups Always true for backend, frontend and mobile ---- {:rules #{{:types :include-list :content {:filename "debit-team-members.txt"}}}} ---- <<< == Always use :app-version Only for mobile ---- {:rules #{{:types :app-version :content {:min-version #{{:platform :android :code 1000000} {:platform :ios :code 2000000}}}}}} ---- <<< == Extend [.line-through]#common-rollout# common-xp if required That's how :include-list, :app-version, etc. were born <<< == Beware of many nested feature flags True for backend, frontend and mobile <<< == Don't delete app-facing feature flags True for mobile <<< == Include a feature flag on the whiteboarding phase <<< == Include deleting/retiring the feature flag at the end <<< == Avoid renaming a feature flag Use :app-version with :min-version instead <<< == And most importantly... <<< == *Always* rely on a feature flag on the app Never do a hotfix, avoid expedited releases at all costs <<< == References // FIXME: links . "Feature Toggles (aka Feature Flags)", by Pete Hodgson . "Continuous integration vs. delivery vs. deployment", by Sten Pittet . Accelerate, by N. Forsgren, J. Humble and G. Kim . these slides: euandre.org/slide/ . prose version of this presentation . view source