Deployment and release are different things. Deployment puts code on servers. Release makes features available to users. Feature flags separate these concerns.
With feature flags, you can deploy daily but release weekly. Ship risky changes but only enable them for 1% of users. Roll back a broken feature in seconds without touching infrastructure.
Basic Implementation 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 class FeatureFlags: def __init__(self): self.flags = {} def is_enabled(self, flag_name: str, user_id: str = None) -> bool: flag = self.flags.get(flag_name) if not flag: return False # Global kill switch if not flag.get("enabled", False): return False # Check user allowlist if user_id and user_id in flag.get("allowed_users", []): return True # Check percentage rollout if user_id and flag.get("percentage", 0) > 0: # Consistent hashing: same user always gets same result hash_val = hash(f"{flag_name}:{user_id}") % 100 return hash_val < flag["percentage"] return flag.get("enabled", False) flags = FeatureFlags() flags.flags = { "new_checkout": { "enabled": True, "percentage": 10, # 10% of users "allowed_users": ["user_123"] # Plus specific users } } # Usage if flags.is_enabled("new_checkout", user_id=current_user.id): return new_checkout_flow() else: return old_checkout_flow() Configuration-Based Flags Store flags in config, not code:
...