Chaturmind
LearnDSASystem DesignDevOpsEngineering GrowthBlog
Start learning
Chaturmind

Structured learning paths for engineers who want to go deep. Written by practitioners.

Learn

  • Java
  • DSA
  • System Design
  • Spring Boot
  • AI / ML
  • DevOps
  • Engineering Growth

Company

  • Blog
  • Contact

Legal

  • Privacy Policy
  • Terms of Service

© 2026 Chaturmind. All rights reserved.

Built for engineers who want to go deep.


← Low-Level Design & Design Patterns

OOP Fundamentals & SOLID Principles

  • Object-Oriented Design Refresher
  • Single Responsibility & Open/Closed
  • Liskov Substitution & Interface Segregation
  • Dependency Inversion

Creational Design Patterns

  • Singleton Pattern
  • Factory & Abstract Factory
  • Builder Pattern
  • Prototype Pattern

Structural Design Patterns

  • Adapter & Facade
  • Decorator Pattern
  • Composite & Proxy
  • Bridge & Flyweight

Behavioral Design Patterns

  • Strategy Pattern
  • Observer Pattern
  • Command Pattern
  • Template Method
  • State Pattern
  • Chain of Responsibility
  • Iterator & Mediator
  • Visitor Pattern

Machine Coding Exercises

  • Parking Lot — Requirements & Class Design
  • Parking Lot — Implementation
  • Elevator System — Requirements & Class Design
  • Elevator System — Implementation & Scheduling
  • Library Management System
  • Tic-Tac-Toe / Board Game Design
  • Chess Engine Design
  • Vending Machine Design
  • ATM System Design
  • In-Memory Rate Limiter
  • Thread-Safe LRU Cache
  • Connection Pool Design
  • Producer-Consumer Class Design
  • Movie Ticket Booking System
  • Hotel Reservation System
  • Airline Booking / Seat Selection System
  • Splitwise / Expense Sharing System
  • Design a Logging Framework
  • Design a Notification/Observer-Based Pub-Sub
  • Design a Cache with Pluggable Eviction Policy
  • Design Snake and Ladder
  • Design a Card Game Framework
  • Design an Inventory Management System
  • Restaurant Management System
  • Food Delivery Order Matching
  • Design a Shopping Cart & Checkout Flow
  • Design a Recommendation Engine
  • Design a Job Scheduler
  • Design a Circuit Breaker
  • Design a Distributed ID Generator
  • Design a Pub-Sub Message Broker
  • Design Twitter/X
  • Multi-Pattern Problem: Design a Ride Booking Class Model
  • Multi-Pattern Problem: Design a Food Ordering Class Model
  • Design an Authentication/Authorization Module
  • Design a Form/Survey Builder
  • Design a Meeting Room / Calendar Booking System
  • Design a Search/Filter Engine for an E-Commerce Catalog
  • Design a Voting/Polling System
  • Design a Retry Mechanism with Backoff
  • Design a Health Check Aggregator
  • Design a Feature Flag System
  • Design a Config Management Client
  • Design a Leader Election Algorithm
  • Design a Distributed Counter
  • Design a Bloom Filter
  • Design a Consistent Hashing Ring
  • Design a Distributed Tracing Library
  • Design a Metrics Collection Library
  • Design an Audit Logging Framework
  • Design a Plugin/Extension System
  • Design a Workflow Engine
  • Multi-Pattern Capstone: Design a Food Delivery App
Chaturmind
← Low-Level Design & Design Patterns

OOP Fundamentals & SOLID Principles

  • Object-Oriented Design Refresher
  • Single Responsibility & Open/Closed
  • Liskov Substitution & Interface Segregation
  • Dependency Inversion

Creational Design Patterns

  • Singleton Pattern
  • Factory & Abstract Factory
  • Builder Pattern
  • Prototype Pattern

Structural Design Patterns

  • Adapter & Facade
  • Decorator Pattern
  • Composite & Proxy
  • Bridge & Flyweight

Behavioral Design Patterns

  • Strategy Pattern
  • Observer Pattern
  • Command Pattern
  • Template Method
  • State Pattern
  • Chain of Responsibility
  • Iterator & Mediator
  • Visitor Pattern

Machine Coding Exercises

  • Parking Lot — Requirements & Class Design
  • Parking Lot — Implementation
  • Elevator System — Requirements & Class Design
  • Elevator System — Implementation & Scheduling
  • Library Management System
  • Tic-Tac-Toe / Board Game Design
  • Chess Engine Design
  • Vending Machine Design
  • ATM System Design
  • In-Memory Rate Limiter
  • Thread-Safe LRU Cache
  • Connection Pool Design
  • Producer-Consumer Class Design
  • Movie Ticket Booking System
  • Hotel Reservation System
  • Airline Booking / Seat Selection System
  • Splitwise / Expense Sharing System
  • Design a Logging Framework
  • Design a Notification/Observer-Based Pub-Sub
  • Design a Cache with Pluggable Eviction Policy
  • Design Snake and Ladder
  • Design a Card Game Framework
  • Design an Inventory Management System
  • Restaurant Management System
  • Food Delivery Order Matching
  • Design a Shopping Cart & Checkout Flow
  • Design a Recommendation Engine
  • Design a Job Scheduler
  • Design a Circuit Breaker
  • Design a Distributed ID Generator
  • Design a Pub-Sub Message Broker
  • Design Twitter/X
  • Multi-Pattern Problem: Design a Ride Booking Class Model
  • Multi-Pattern Problem: Design a Food Ordering Class Model
  • Design an Authentication/Authorization Module
  • Design a Form/Survey Builder
  • Design a Meeting Room / Calendar Booking System
  • Design a Search/Filter Engine for an E-Commerce Catalog
  • Design a Voting/Polling System
  • Design a Retry Mechanism with Backoff
  • Design a Health Check Aggregator
  • Design a Feature Flag System
  • Design a Config Management Client
  • Design a Leader Election Algorithm
  • Design a Distributed Counter
  • Design a Bloom Filter
  • Design a Consistent Hashing Ring
  • Design a Distributed Tracing Library
  • Design a Metrics Collection Library
  • Design an Audit Logging Framework
  • Design a Plugin/Extension System
  • Design a Workflow Engine
  • Multi-Pattern Capstone: Design a Food Delivery App
HomeLearnSystem DesignLow-Level Design & Design PatternsMachine Coding Exercises
✓ FreeIntermediate· 7 min read

Design a Feature Flag System

FeatureFlag, FlagEvaluator, TargetingRule, and FlagRepository as the core classes, implementing percentage-rollout and user-targeted evaluation, and the local-caching-vs-central-query latency/freshness trade-off.

Published September 23, 2026


Design a Feature Flag System

Core classes

class FeatureFlag { String key; boolean enabled; List<TargetingRule> rules; int rolloutPercentage; }
interface TargetingRule { boolean matches(User user); }
interface FlagEvaluator { boolean isEnabled(String flagKey, User user); }
interface FlagRepository { FeatureFlag getFlag(String key); }

Separating TargetingRule (WHO a flag applies to) from the flag's simple enabled/rolloutPercentage fields lets targeting logic grow in sophistication (a specific user list, an account-tier rule, a geographic rule) without changing FeatureFlag's own structure — each rule type is its own small implementation behind one interface.

Percentage-rollout evaluation

class PercentageRolloutEvaluator implements FlagEvaluator {
    public boolean isEnabled(String flagKey, User user) {
        FeatureFlag flag = repository.getFlag(flagKey);
        if (!flag.enabled) return false;
        int bucket = Math.abs((flagKey + user.getId()).hashCode()) % 100; // deterministic per user+flag
        return bucket < flag.rolloutPercentage;
    }
}

The critical correctness property here: hashing flagKey + userId (not a random number generated fresh each time) is what makes the SAME user consistently get the SAME rollout decision for a given flag across repeated evaluations — a user who's "in" the 20% rollout stays in it on every subsequent request, rather than flickering between enabled/disabled randomly, which would produce a genuinely broken, inconsistent user experience.

Targeted rules combined with percentage rollout

class CompositeFlagEvaluator implements FlagEvaluator {
    public boolean isEnabled(String flagKey, User user) {
        FeatureFlag flag = repository.getFlag(flagKey);
        if (!flag.enabled) return false;
        if (flag.rules.stream().anyMatch(rule -> rule.matches(user))) return true; // explicit override
        return percentageRolloutEvaluator.isEnabled(flagKey, user); // fall through to percentage logic
    }
}

A common real requirement: an explicit targeting rule ("always on for internal employees, regardless of the rollout percentage") should OVERRIDE the percentage-based decision — checking explicit rules first, and only falling through to percentage-rollout logic if no rule matches, gives predictable, layered precedence rather than an ambiguous combination of both mechanisms.

Local caching vs always querying centrally

Always query central service:  every evaluation is always up-to-date, but adds a
  network round-trip (and a new failure mode) to EVERY flag check
Local cache, periodic refresh:  fast (in-memory check), but a flag TOGGLED centrally
  takes up to the refresh interval to actually take effect everywhere

This is a genuine latency-vs-freshness trade-off, directly connecting to Health Checks' broader essential-dependency reasoning: a feature flag check happening on a hot request path (evaluated on every single request) cannot reasonably afford a network call per evaluation — local caching with periodic background refresh (or a push-based update via the Observer pattern used in Design a Config Management Client) is the standard, practical answer, accepting a bounded propagation delay for a toggle change in exchange for evaluation staying fast and not adding a new failure dependency to every single request.

Follow-up questions this topic invites — and their answers

Q: What happens to flag evaluation if the local cache hasn't been populated yet (a fresh service instance just started)? A: A sensible DEFAULT VALUE per flag (baked into the flag's own definition, defaulting to 'off' for a new feature) is needed for exactly this gap — evaluating against a not-yet-populated cache should fail safely to the flag's stated default, not throw an error or silently treat every flag as enabled.

Q: How would you support an emergency 'kill switch' that needs to take effect immediately, bypassing the normal refresh interval? A: A push-based invalidation mechanism (the flag service notifying subscribed instances immediately on a critical change, rather than waiting for the next periodic poll) is the standard answer for this specific case — most feature flag platforms support exactly this dual mode: periodic refresh for normal changes, immediate push for emergency ones.

Q: Does hashing flagKey+userId for percentage rollout have any weaknesses? A: A weak or poorly-distributed hash function could produce uneven bucketing (some percentage ranges getting disproportionately more users than others) — a well-distributed hash (like a standard cryptographic or MurmurHash-style function, rather than relying purely on Java's default hashCode(), which isn't guaranteed to distribute evenly) is the more correct production choice.

Q: How does this relate to Design a Config Management Client, covered next? A: A feature flag system IS, structurally, a specialized config management client — flags are a specific KIND of dynamically-updatable configuration value, and the caching/freshness trade-off and Observer-based update propagation discussed there apply directly to feature flags too; many real systems build feature flagging as a thin layer on top of a more general config-management foundation rather than as an entirely separate system.

Previous

Design a Health Check Aggregator

Next

Design a Config Management Client

AI Tutor

Lesson: Design a Feature Flag System

Quick actions

AI responses can be inaccurate. Verify critical information.