Production-ready workflow for safely retiring feature flags with checklists, timelines, and automation.
Production-ready workflow for safely retiring feature flags with checklists, timelines, and automation.
Feature flag retirement is critical to prevent technical debt. This workflow ensures safe, systematic flag removal.
Objective: Identify flags ready for retirement
Checklist:
Analysis:
# Check flag usage
./analyze_flag_usage.py track --flag feature-x --days 90
# Check stale flags
./analyze_flag_usage.py stale --threshold 90 --flags-file flags.json
# Get retirement recommendations
./analyze_flag_usage.py recommend-retire \
--confidence 0.8 \
--flags-file flags.json
Criteria for Retirement:
Output: List of candidate flags with confidence scores
Objective: Create detailed retirement plan
Tasks:
```bash # Find all code references grep -r "feature-x" --include=".py" --include=".js" .
# Or use the analysis tool ./analyze_flag_usage.py debt --flag feature-x --flags-file flags.json ```
| Area | Impact Level | Notes | |------|-------------|-------| | Frontend | Low | Only in 2 components | | Backend | Medium | Used in 5 services | | Mobile | None | Not used | | Analytics | High | Multiple dashboards | | Tests | Medium | 15 tests reference flag |
Output: Retirement plan document
Objective: Notify stakeholders and prepare teams
Communication Plan:
``` Subject: Feature Flag Retirement: feature-x
We plan to retire the 'feature-x' feature flag in 2 weeks.
Timeline:
Impact:
Action Required:
Questions? Contact: [Team] ```
Checklist:
Objective: Mark flag as deprecated and prepare for removal
Steps:
```python # Python example import warnings
def check_feature_x(): warnings.warn( "feature-x flag is deprecated and will be removed in v2.0", DeprecationWarning, stacklevel=2 ) return feature_flags.is_enabled('feature-x') ```
``javascript // JavaScript example function checkFeatureX() { console.warn('feature-x flag is deprecated and will be removed in v2.0'); return featureFlags.isEnabled('feature-x'); } ``
``bash # Using management tool ./manage_feature_flags.py update \ --key feature-x \ --environment production \ --description "DEPRECATED: Will be removed 2025-02-01" ``
```python # Test that flag can be safely removed def test_feature_x_removal(): # Verify default behavior result = get_feature_behavior(flag_enabled=False) assert result == expected_default_behavior
# Verify flag enabled behavior (should be same) result = get_feature_behavior(flag_enabled=True) assert result == expected_default_behavior ```
Checklist:
Objective: Remove flag references from code
Process:
``bash git checkout -b remove-feature-x-flag ``
```python # Before if feature_flags.is_enabled('feature-x'): new_implementation() else: legacy_implementation()
# After (keep winning variation) new_implementation() ```
```python # Before @parametrize('flag_enabled', [True, False]) def test_feature_x(flag_enabled): # Test both paths pass
# After def test_feature_x(): # Test single path pass ```
Automated Cleanup Tool:
# Find and replace
find . -type f -name "*.py" -exec sed -i '' \
'/feature-x/d' {} +
# Verify changes
git diff --stat
Checklist:
Objective: Remove flag from provider and configuration
Steps:
``bash ./manage_feature_flags.py toggle \ --key feature-x \ --environment production \ --enabled false ``
``bash ./manage_feature_flags.py archive \ --key feature-x \ --environment production ``
``bash git add . git commit -m "Remove feature-x flag after successful rollout" git push origin remove-feature-x-flag ``
Monitoring Checklist:
Objective: Verify complete removal and cleanup
Verification Steps:
```bash # Ensure no references remain grep -r "feature-x" . --include=".py" --include=".js"
# Should return no results ```
``bash # Verify flag is archived ./manage_feature_flags.py list \ --environment production \ --archived true | grep feature-x ``
Final Checklist:
| Week | Phase | Key Activities | |------|-------|----------------| | 1 | Identification | Analyze usage, get approvals | | 2 | Planning | Map dependencies, create plan | | 2-3 | Communication | Notify stakeholders | | 3 | Deprecation | Mark deprecated, add warnings | | 4 | Code Cleanup | Remove flag checks | | 4-5 | Flag Removal | Archive flag, deploy changes | | 5-6 | Verification | Confirm complete removal |
#!/bin/bash
# find_retirement_candidates.sh
./analyze_flag_usage.py recommend-retire \
--confidence 0.8 \
--flags-file flags.json \
--json > candidates.json
# Generate report
./analyze_flag_usage.py report \
--results candidates.json \
--format html \
--output retirement_candidates.html
#!/bin/bash
# scan_flag_references.sh
FLAG_KEY=$1
echo "Scanning for references to: $FLAG_KEY"
# Find in code
echo "=== Code References ==="
rg "$FLAG_KEY" --type py --type js --type go
# Find in configs
echo "=== Config References ==="
find . -name "*.yaml" -o -name "*.json" | xargs grep "$FLAG_KEY"
# Find in tests
echo "=== Test References ==="
rg "$FLAG_KEY" --glob "*test*"
#!/bin/bash
# verify_safe_removal.sh
FLAG_KEY=$1
echo "Verifying safe removal of: $FLAG_KEY"
# Check usage stats
./analyze_flag_usage.py track --flag "$FLAG_KEY" --days 90
# Check for dependencies
./analyze_flag_usage.py debt --flag "$FLAG_KEY"
# Run tests
pytest tests/ -v
echo "Verification complete"
If issues detected after flag removal:
```bash # Revert deployment kubectl rollout undo deployment/app
# Or revert via CD tool argocd app rollback app-production ```
``bash # Re-create flag if deleted ./manage_feature_flags.py create \ --key feature-x \ --name "Feature X (Restored)" \ --type release \ --variations '{"on": true, "off": false}' \ --default off \ --enabled ``
manage_feature_flags.py: Flag CRUD operationsanalyze_flag_usage.py: Usage analyticstest_flag_variations.py: Validation testingFollow this workflow to safely retire feature flags without disruption. Take time, communicate well, and monitor carefully.