From 8c549ee11ac446fb8865f2e43f10fd2867d1794d Mon Sep 17 00:00:00 2001 From: LEE GATHERCOLE Date: Wed, 28 May 2025 14:44:57 +0100 Subject: [PATCH 1/6] Added comments section --- practices/feature-toggling.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/practices/feature-toggling.md b/practices/feature-toggling.md index 88f0e3bd..94611465 100644 --- a/practices/feature-toggling.md +++ b/practices/feature-toggling.md @@ -15,6 +15,7 @@ - [Best practice lifecycle](#best-practice-lifecycle) - [Testing toggled features](#testing-toggled-features) - [Designing for failure](#designing-for-failure) + - [Comments](#comments) - [Further reading](#further-reading) ## Context @@ -132,6 +133,8 @@ Best practices: - Graceful degradation: Systems should still function, possibly with reduced capability, if a toggle cannot be resolved. - Resilient integration: Ensure that SDKs or services used for toggling are resilient and do not block application startup or core functionality. +## Comments + ## Further reading - [Feature Toggles by Martin Fowler](https://martinfowler.com/articles/feature-toggles.html) From 13de075ff15ce2cc8847aec56c1f2b1cee6aa339 Mon Sep 17 00:00:00 2001 From: LEE GATHERCOLE Date: Wed, 28 May 2025 14:54:15 +0100 Subject: [PATCH 2/6] Resolve dead link message --- patterns/little-and-often.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/patterns/little-and-often.md b/patterns/little-and-often.md index 9e2616a1..41cf7f87 100644 --- a/patterns/little-and-often.md +++ b/patterns/little-and-often.md @@ -48,7 +48,7 @@ This pattern is in essence very straightforward; the power comes in applying it - **Delivering software.** The trivial and obvious example of this pattern is that it is better to deliver software in small increments than to do it in one [big bang](https://hackernoon.com/why-your-big-bang-multi-year-project-will-fail-988e45c830af). - **Planning.** Start by doing just enough planning to forecast the size and type of team(s) you need to get the job done roughly when you want it to be done by. Incrementally refine that plan through (typically) fortnightly backlog/roadmap refinement sessions. -- **User-centred design.** User research and design activities ([SERVICE-USER](https://www.gov.uk/service-manual/user-research), [SERVICE-DESIGN](https://www.gov.uk/service-manual/design)) occur in all phases of an agile delivery: [discovery](https://www.gov.uk/service-manual/agile-delivery/how-the-discovery-phase-works), [alpha](https://www.gov.uk/service-manual/agile-delivery/how-the-alpha-phase-works), [beta](https://www.gov.uk/service-manual/agile-delivery/how-the-beta-phase-works) and [live](https://www.gov.uk/service-manual/agile-delivery/how-the-live-phase-works) ([SERVICE-PHASES](https://www.gov.uk/service-manual/agile-delivery)). Delivery in all phases is done using [build-measure-learn](http://theleanstartup.com/principles#:~:text=A%20core%20component%20of%20Lean,feedback%20loop.) loops, with the whole multi-disciplinary team working closely together in all three activities. This approach means that rather than having a big up front design, the design is iteratively refined throughout all phases ([SERVICE-AGILE](https://www.gov.uk/service-manual/agile-delivery/agile-government-services-introduction#the-differences-between-traditional-and-agile-methods)). +- **User-centred design.** User research and design activities ([SERVICE-USER](https://www.gov.uk/service-manual/user-research), [SERVICE-DESIGN](https://www.gov.uk/service-manual/design)) occur in all phases of an agile delivery: [discovery](https://www.gov.uk/service-manual/agile-delivery/how-the-discovery-phase-works), [alpha](https://www.gov.uk/service-manual/agile-delivery/how-the-alpha-phase-works), [beta](https://www.gov.uk/service-manual/agile-delivery/how-the-beta-phase-works) and [live](https://www.gov.uk/service-manual/agile-delivery/how-the-live-phase-works) ([SERVICE-PHASES](https://www.gov.uk/service-manual/agile-delivery)). Delivery in all phases is done using [build-measure-learn](http://theleanstartup.com/principles#:~:text=A%20core%20component%20of%20Lean,feedback%20loop) loops, with the whole multi-disciplinary team working closely together in all three activities. This approach means that rather than having a big up front design, the design is iteratively refined throughout all phases ([SERVICE-AGILE](https://www.gov.uk/service-manual/agile-delivery/agile-government-services-introduction#the-differences-between-traditional-and-agile-methods)). - **Technical design and architecture.** While some up front thinking is generally beneficial to help a delivery team set off in the right direction, the output design is best viewed as first draft which will be refined during delivery as more is discovered about technical and product constraints and opportunities. See [Evolutionary Architectures](https://evolutionaryarchitecture.com/precis.html). - **Team processes.** Great team processes come about by starting with something simple and practising [continuous improvement](https://kanbanize.com/lean-management/improvement/what-is-continuous-improvement) to find ways of working, definitions of done and so on which are well suited to the particular team and environment. From 1e5d03f3d4242186b28e97cb14e4e3dcd96de9c2 Mon Sep 17 00:00:00 2001 From: Dan Stefaniuk Date: Wed, 28 May 2025 16:45:00 +0100 Subject: [PATCH 3/6] Revise content --- practices/feature-toggling.md | 46 +++++++++++++++++++---------------- 1 file changed, 25 insertions(+), 21 deletions(-) diff --git a/practices/feature-toggling.md b/practices/feature-toggling.md index 94611465..91619c46 100644 --- a/practices/feature-toggling.md +++ b/practices/feature-toggling.md @@ -15,7 +15,6 @@ - [Best practice lifecycle](#best-practice-lifecycle) - [Testing toggled features](#testing-toggled-features) - [Designing for failure](#designing-for-failure) - - [Comments](#comments) - [Further reading](#further-reading) ## Context @@ -42,7 +41,7 @@ This is particularly powerful in continuous delivery environments where small, f For a detailed and widely referenced introduction to this practice, see Martin Fowler's article on [Feature Toggles](https://martinfowler.com/articles/feature-toggles.html). -While some areas are looking to adopt a more enterprise-grade offering with Flagsmith, it's important to recognise that more minimal feature toggle approaches may be appropriate for smaller or simpler systems. The [Thoughtworks Technology Radar](https://www.thoughtworks.com/radar) notes that many teams over-engineer feature flagging by immediately adopting complex platforms, when a simpler approach (e.g., environment variables or static config) would suffice. However, irrespective of how the toggle is implemented, the **governance, traceability, and lifecycle management processes should be consistent**. +While some areas are looking to adopt a more enterprise-grade offering with a dedicated feature toggling tool, it's important to recognise that more minimal feature toggle approaches may be appropriate for smaller or simpler systems. The [Thoughtworks Technology Radar](https://www.thoughtworks.com/radar) notes that many teams over-engineer feature flagging by immediately adopting complex platforms, when a simpler approach (e.g., environment variables or static config) would suffice. However, irrespective of how the toggle is implemented, the **governance, traceability, and lifecycle management processes should be consistent**. ## What is feature toggling? @@ -52,9 +51,9 @@ Toggles can be defined statically (e.g., environment variable or config file) or ## Why use feature toggling? -- **Decouple deployment from release**: Code can be deployed behind a toggle and activated later. +- **Decouple deployment from release**: Deploy code behind a toggle and activate it later. - **Enable safe rollouts**: Enable features for specific users or teams to validate functionality before full rollout. -- **Support operational control**: Temporarily disable a feature causing issues without rollback. +- **Support operational control**: Temporarily disable a feature which is causing issues, without needing to rollback. - **Enable experimentation**: Run A/B tests to determine user impact. - **Configure environment-specific behaviour**: Activate features in dev or test environments only. @@ -67,16 +66,20 @@ According to Martin Fowler, toggles typically fall into the following categories - **Ops toggles**: Provide operational control for performance or reliability. - **Permission toggles**: Enable features based on user roles or attributes. +> [!NOTE] +> While permission toggles can target users by role or attribute during a rollout or experiment, they are not a replacement for robust, permanent role-based access control (RBAC). Use RBAC as a separate, first-class mechanism for managing user permissions. + ## Managing toggles Poorly managed toggles can lead to complexity, bugs, and technical debt. Best practices include: - Give toggles meaningful, consistent names. -- Store toggle state in a centralised and observable system. - Document the purpose and expected lifetime of each toggle. -- Remove stale toggles once their purpose is fulfilled. Ideally integrate this into your CI pipeline to report on stale flags. -- Avoid nesting toggles or creating toggle spaghetti. +- Store toggle state in an observable system. +- Guard the feature behind a single toggle check, and pass the resulting behaviour or strategy through your code to minimise duplication and simplify removal. - Ensure toggles are discoverable, testable, and auditable. +- Avoid nesting toggles or creating toggle spaghetti. +- Remove stale toggles once their purpose is fulfilled. ## Caveats @@ -92,7 +95,7 @@ Whilst there are obvious benefits to Feature Toggling, there are some caveats wo Choose a feature flagging approach appropriate for the scale and complexity of your system: - **Simple applications**: Environment variables or configuration files. -- **Moderate scale and beyond**: Look to make use of e.g. [Flagsmith](https://www.flagsmith.com/), which supports targeting, analytics, and team workflows. +- **Moderate scale and beyond**: Look to make use of a dedicated feature toggling tool, which supports targeting, analytics, and team workflows. Feature toggles should be queryable from all components that need access to their values. Depending on your architecture, this may require synchronisation, caching, or SDK integration. @@ -115,16 +118,21 @@ Document toggles in your architecture or delivery tooling to ensure visibility a Features behind toggles should be tested in both their enabled and disabled states. This ensures correctness regardless of the toggle value. -- Write tests that explicitly set the toggle on and off. -- Use test frameworks that allow injecting or mocking toggle values. -- Consider test coverage for the toggle transitions (e.g., changing at runtime). -- Ensure integration and end-to-end tests include scenarios where toggles are disabled. +- Prefer testing the behaviour behind the toggle (e.g. via Strategy implementations) directly, rather than toggling features within tests. +- Where the Strategy Pattern is used, write separate unit tests for each strategy to validate their behaviour in isolation. +- If toggling is required in tests, use frameworks that allow injecting or mocking toggle values cleanly. +- Ensure integration and end-to-end tests include scenarios with the toggle both enabled and disabled, especially if the toggle is expected to persist across multiple releases. +- Include toggle state in test names or descriptions to clarify test intent (e.g. `shouldReturnNull_whenFeatureDisabled()`). +- Track test coverage across both toggle states and regularly review it for long-lived or critical toggles. +- Ensure test coverage includes edge cases introduced by toggled logic, such as different user roles, environment-specific behaviour, or state transitions. +- Use contract tests where toggled behaviour affects external APIs or integrations to ensure they remain backward-compatible. +- Avoid asserting on the presence or structure of toggle code itself, focus on testing expected outcomes. This is particularly important for toggles that persist for more than one release cycle. ## Designing for failure -Feature toggles should never become a point of failure. Design your system so that it behaves predictably even if the toggle service is unavailable or fails to return a value. +If you are using a feature toggle service external to the application, feature toggles should never become a point of failure. Design your system so that it behaves predictably even if the toggle service is unavailable or fails to return a value. Best practices: @@ -133,13 +141,9 @@ Best practices: - Graceful degradation: Systems should still function, possibly with reduced capability, if a toggle cannot be resolved. - Resilient integration: Ensure that SDKs or services used for toggling are resilient and do not block application startup or core functionality. -## Comments - ## Further reading -- [Feature Toggles by Martin Fowler](https://martinfowler.com/articles/feature-toggles.html) -- [Unleash Strategies and Best Practices](https://docs.getunleash.io/topics/feature-flags/feature-flag-best-practices) -- [Flagsmith Docs](https://docs.flagsmith.com/) -- [Feature Flag Best Practices](https://launchdarkly.com/blog/best-practices-for-coding-with-feature-flags/) -- [Thoughtworks Tech Radar](https://www.thoughtworks.com/radar/techniques/minimum-feature-toggle-solution) -- [Defensive coding](https://docs.flagsmith.com/guides-and-examples/defensive-coding) +- [Feature Toggles (aka Feature Flags) by Martin Fowler](https://martinfowler.com/articles/feature-toggles.html) +- [11 principles for building and scaling feature flag systems](https://docs.getunleash.io/topics/feature-flags/feature-flag-best-practices) +- [Best practices for coding with feature flags](https://launchdarkly.com/blog/best-practices-for-coding-with-feature-flags/) +- [An example tool for feature toggling](https://docs.flagsmith.com/) From a29dbc771b46be83fe9e21cf16bc7a1ecf98125d Mon Sep 17 00:00:00 2001 From: Dan Stefaniuk Date: Fri, 30 May 2025 11:58:37 +0100 Subject: [PATCH 4/6] More content --- practices/feature-toggling.md | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/practices/feature-toggling.md b/practices/feature-toggling.md index 91619c46..cefd46dd 100644 --- a/practices/feature-toggling.md +++ b/practices/feature-toggling.md @@ -79,7 +79,16 @@ Poorly managed toggles can lead to complexity, bugs, and technical debt. Best pr - Guard the feature behind a single toggle check, and pass the resulting behaviour or strategy through your code to minimise duplication and simplify removal. - Ensure toggles are discoverable, testable, and auditable. - Avoid nesting toggles or creating toggle spaghetti. -- Remove stale toggles once their purpose is fulfilled. +- Remove stale toggles once their purpose is fulfilled. Ideally integrate this into your CI pipeline to report on stale flags. + +## Caveats + +Whilst there are obvious benefits to Feature Toggling, there are some caveats worth bearing in mind when implementing them + +- **Performance Overhead**: Feature toggles can introduce performance overhead if they are checked frequently, especially within loops and every evaluation goes back to the server. +- **Toggle Bloat & Technical Debt**: Toggles are intended for short term use, failure to adhere to this principle can lead to conditional sprawl of if statements, harder code to read and maintain and increased risk of toggle conflicts or becoming orphaned +- **Test Complexity**: More toggles increase your permutations around a single test path. A single toggle doubles the test scenarios and needs careful factoring in to the test approach. +- **Increased Logging/Observability Needs**; Now need to know the state of the toggles at the point of the logs, otherwise inspecting the logs becomes incredibly difficult. ## Caveats @@ -146,4 +155,5 @@ Best practices: - [Feature Toggles (aka Feature Flags) by Martin Fowler](https://martinfowler.com/articles/feature-toggles.html) - [11 principles for building and scaling feature flag systems](https://docs.getunleash.io/topics/feature-flags/feature-flag-best-practices) - [Best practices for coding with feature flags](https://launchdarkly.com/blog/best-practices-for-coding-with-feature-flags/) +- [Defensive coding](https://docs.flagsmith.com/guides-and-examples/defensive-coding) - [An example tool for feature toggling](https://docs.flagsmith.com/) From c265f25e45145b0ace5a7b73bca2297aead0069d Mon Sep 17 00:00:00 2001 From: Dan Stefaniuk Date: Fri, 30 May 2025 12:03:42 +0100 Subject: [PATCH 5/6] Clean up --- practices/feature-toggling.md | 9 --------- 1 file changed, 9 deletions(-) diff --git a/practices/feature-toggling.md b/practices/feature-toggling.md index cefd46dd..c7adf1c2 100644 --- a/practices/feature-toggling.md +++ b/practices/feature-toggling.md @@ -90,15 +90,6 @@ Whilst there are obvious benefits to Feature Toggling, there are some caveats wo - **Test Complexity**: More toggles increase your permutations around a single test path. A single toggle doubles the test scenarios and needs careful factoring in to the test approach. - **Increased Logging/Observability Needs**; Now need to know the state of the toggles at the point of the logs, otherwise inspecting the logs becomes incredibly difficult. -## Caveats - -Whilst there are obvious benefits to Feature Toggling, there are some caveats worth bearing in mind when implementing them - -- **Performance Overhead**: Feature toggles can introduce performance overhead if they are checked frequently, especially within loops and every evaluation goes back to the server. -- **Toggle Bloat & Technical Debt**: Toggles are intended for short term use, failure to adhere to this principle can lead to conditional sprawl of if statements, harder code to read and maintain and increased risk of toggle conflicts or becoming orphaned -- **Test Complexity**: More toggles increase your permutations around a single test path. A single toggle doubles the test scenarios and needs careful factoring in to the test approach. -- **Increased Logging/Observability Needs**; Now need to know the state of the toggles at the point of the logs, otherwise inspecting the logs becomes incredibly difficult. - ## Toggling strategy Choose a feature flagging approach appropriate for the scale and complexity of your system: From a81f77c9afd0de753b03b3addc035144b86bf368 Mon Sep 17 00:00:00 2001 From: Dan Stefaniuk Date: Fri, 30 May 2025 12:05:24 +0100 Subject: [PATCH 6/6] Include link --- practices/feature-toggling.md | 1 + 1 file changed, 1 insertion(+) diff --git a/practices/feature-toggling.md b/practices/feature-toggling.md index c7adf1c2..c405b743 100644 --- a/practices/feature-toggling.md +++ b/practices/feature-toggling.md @@ -144,6 +144,7 @@ Best practices: ## Further reading - [Feature Toggles (aka Feature Flags) by Martin Fowler](https://martinfowler.com/articles/feature-toggles.html) +- [Thoughtworks Tech Radar](https://www.thoughtworks.com/radar/techniques/simplest-possible-feature-toggle) - [11 principles for building and scaling feature flag systems](https://docs.getunleash.io/topics/feature-flags/feature-flag-best-practices) - [Best practices for coding with feature flags](https://launchdarkly.com/blog/best-practices-for-coding-with-feature-flags/) - [Defensive coding](https://docs.flagsmith.com/guides-and-examples/defensive-coding)