How to Mock a Feature Flag Rollout Percentage in Python
Simulate a percentage-based feature flag rollout by hashing a user ID to deterministically enable features for a subset of users.
Python code
22 linesimport random
from dataclasses import dataclass
@dataclass
class FeatureFlag:
name: str
rollout_percentage: int
def is_feature_enabled(feature_flag: FeatureFlag, user_id: str) -> bool:
hashed_id = hash(user_id) % 100
return hashed_id < feature_flag.rollout_percentage
if __name__ == "__main__":
flag = FeatureFlag(name="new_checkout", rollout_percentage=25)
users = ["alice", "bob", "carol", "dave", "eve", "frank", "grace", "heidi"]
for user in users:
enabled = is_feature_enabled(flag, user)
print(f"User {user:8s} -> feature {'ENABLED' if enabled else 'disabled'}")
Output
User alice -> feature disabled
User bob -> feature disabled
User carol -> feature ENABLED
User dave -> feature disabled
User eve -> feature disabled
User frank -> feature disabled
User grace -> feature ENABLED
User heidi -> feature disabled
How it works
The hash(user_id) call produces a deterministic integer for the same string within a single Python run, and % 100 maps it to a 0-99 range. Comparing that value against the rollout percentage gives a stable 25% chance that any given user sees the feature enabled. Using a hash (rather than random) means the same user consistently gets the same result, which keeps the rollout predictable across requests. This simple approach works well for local testing and shadows real-world feature flag services like LaunchDarkly.
Common mistakes
- Using `random.randint` or `random.random` which gives different results each call — breaking determinism for the same user
- Forgetting that Python's `hash()` is salted per process so results differ across runs — use a stable hash like `hashlib.md5` in production
- Not wrapping the modulo, which can produce negative values on some platforms unless you use `abs()` or `& 0xffffffff`
Variations
- Use `hashlib.md5(user_id.encode()).hexdigest()` to get a stable hash across runs and platforms for production use
- Implement with `random.Random(user_id).randint(0, 99)` for a slower but run-independent deterministic result
Real-world use cases
- Testing a new checkout flow with a staged rollout to a small percentage of production users before full release.
- Shadow-deploying an internal dashboard feature where a stable subset of employees see the new UI first.
- Simulating gradual feature adoption in a demo or staging environment without a paid feature-flag service.
Sponsored
More from Production deployment patterns
- Auto Rollback on Error Rate Exceeded in Python medium
- Automate Semantic Versioning with Conventional Commits in Python medium
- Design a Data Helper for Beginners in Python easy
- Docker healthcheck CMD mock in Python easy
- Generate a Mock Artifact Version Tag in Python easy
- Generate a docker-compose.yml with mock services in Python easy
Keep learning
Related tutorials and quizzes for this topic.