Your feature-flag test matrix has 30 flags — do you still enumerate all 2^n configurations?
answer
- Is a billion configurations a compute problem?
- What is the exponent, and who controls it?
- Do all thirty flags actually interact?
- Most defects involve only a pair
- Renegotiate the requirement, not the generator
basics
~20 sNo. Thirty flags means over a billion configurations, and no pruning trick rescues an exponent you have no constraints to prune with. The work becomes scoping: enumerate only within interacting groups, encode real constraints, cover the rest pairwise, and cap flag growth.
solid answer
~50 sAt thirty flags the power set is over a billion configurations, and the honest answer is that exhaustive enumeration stopped being an algorithm question and became a scoping one. Generating the configurations is not even the expensive part — they can be streamed one at a time in constant extra memory; the cost is running something against each. So I attack the exponent rather than the generator, in three moves. First, partition the flags into groups that genuinely interact and enumerate each group exhaustively, turning one huge power set into a sum of small ones. Second, encode the real constraints — mutually exclusive flags, flags gated by others — so the search prunes infeasible configurations instead of producing them. Third, cover cross-group interactions with a pairwise set, which is tens of configurations rather than a billion and catches most interaction defects. Then I make flag growth itself a policy, with a budget and expiry dates, because the exponent is the only variable anyone can actually move.
go deeper
Know that doubling the number of on/off switches doubles the configuration count, so thirty of them is around a billion. Recognising that a plan is out of budget is more valuable here than proposing a fix.
Explain why no pruning saves an unconstrained exponential, and separate the cost of generating configurations from the cost of doing something with each one. The generator is not the bottleneck.
Show the concrete moves: partition into interacting groups so the cost becomes a sum of small power sets, encode real flag constraints so infeasible branches are pruned, and use a pairwise covering set for the rest.
Own the requirement and the coverage claim. Say what you will and will not test in writing, put a named owner on the independence assumption, and treat the flag count itself as a governed budget with expiry dates rather than a given.
## The number first Thirty independent on/off flags give 2^30 configurations, which is 1,073,741,824. If exercising one configuration costs a single millisecond, the full sweep is about twelve and a half days of wall clock; at a realistic integration-test cost of seconds, it is centuries. There is no cleverness that recovers this. Recognising that instantly, and saying the number out loud rather than reaching for an optimisation, is most of what the question tests. A useful companion fact is where the ceiling actually sits. Exhaustive subset enumeration stays practical to roughly twenty candidates — about a million configurations — and is uncomfortable but survivable at twenty-five, around thirty-three million. Enumerating orderings dies far earlier: ten items is already 3,628,800 and twelve is 479,001,600. Knowing these thresholds lets you answer "is this technique viable here?" before you design anything around it. ## Separate the generator from the work A common wrong turn is to optimise the enumeration itself — make it iterative, stream it, parallelise it. The generator is genuinely cheap: you can emit configurations one at a time with constant extra state, and a billion cheap emissions is not what hurts. The expense is entirely per-configuration downstream work: spinning an environment, running a suite, a human looking at a failure. Anything that leaves the count at 2^30 has not helped. **The only lever that matters is reducing how many configurations you act on.** That reframing is what separates a principal answer from a strong senior one. The senior answer optimises the search; the principal answer changes what is being searched. ## Move one: attack the exponent by partitioning Most flag sets are not one interacting mass. They are several loosely coupled clusters — a few flags governing a checkout path, a few governing a rendering mode, a few operational kill switches that touch nothing else. If the flags split into groups of, say, 8, 7, 8 and 7 with no cross-group interaction, exhaustive coverage costs 2^8 + 2^7 + 2^8 + 2^7, which is 768 configurations rather than a billion. Turning a product into a sum is the single biggest win available, and it is available surprisingly often. The risk is that independence is an *assumption*, not a fact. If two groups secretly interact, no configuration you run will ever exercise that pair, and the gap is invisible — the suite is green because the case was never generated. So the partition needs an owner, a documented rationale, and a re-check whenever a flag moves or is added. ## Move two: encode the constraints you already have Real flag sets are full of rules: these two are mutually exclusive, this one is meaningless unless that one is on, this trio is a three-way mode selector rather than three independent booleans. Every such rule collapses branches. A three-way mode expressed as three booleans contributes 8 combinations of which only 3 are legal. Encoding the constraints and pruning infeasible branches during the search — rather than generating everything and filtering — can shrink a space by orders of magnitude for free, and it also documents the flag semantics somewhere executable. Be honest about what this buys: the pruned space is smaller but still exponential in the number of genuinely free flags. Constraints turn 2^30 into something like 2^22. That is a huge improvement and still nowhere near runnable, which is why this move alone is not an answer. ## Move three: buy coverage instead of completeness Most interaction defects involve a small number of interacting flags, usually two. A pairwise covering set is a small collection of configurations chosen so that every pair of flag settings — every combination of "flag A on, flag B off" and so on, over all pairs — appears in at least one configuration. For thirty binary flags such a set is famously tiny, on the order of ten configurations. Extending to every three-way combination costs a few times more and is still nowhere near exponential. The engineering discipline here is stating the claim precisely. "We test every pair of flag settings, plus this hand-picked list of business-critical combinations; we do not exercise arbitrary three-way interactions" is a defensible position. "We test the flags" is not. Silently sampling while implying completeness is the failure mode that gets found in a post-incident review. ## Move four: treat the exponent as an organisational variable The deepest answer is that thirty flags is itself the defect. Flags accumulate because adding one is trivial and removing one requires someone to confirm the old path is dead. Nobody owns the count, so it only rises, and every addition doubles the space. The durable fixes are policy, not code: a cap on live flags, an expiry date attached at creation, a periodic sweep that deletes flags whose experiment has concluded, and a rule that a permanent behaviour switch is configuration rather than a flag. Reducing thirty flags to eighteen is a factor of four thousand, which no amount of algorithmic work will ever match. Naming that is the part of the answer that shows you are thinking about the system rather than the search. ## How to close Say the number, refuse the exhaustive plan, give the ordered moves — partition, constrain, cover pairwise, then govern the count — and state the coverage claim you would be willing to put in writing. The interviewer is checking whether you know when a technique is out of budget and whether you can renegotiate a requirement rather than quietly under-deliver on it.
- Above what input size does exhaustive enumeration stop being practical, and does it differ by shape?Sharply. Subset enumeration is comfortable to about twenty candidates, roughly a million configurations, and strained by twenty-five at thirty-three million. Ordering enumeration dies far earlier: ten items is already 3.6 million and twelve is 479 million. Same technique, wildly different ceilings, so the first question is always which state space you are in.
- How would you defend running only pairwise coverage to a sceptical stakeholder?By stating the claim precisely rather than implying completeness: every pair of flag settings is exercised at least once, plus a hand-picked list of business-critical combinations enumerated exhaustively; arbitrary three-way interactions are not covered. Then name the residual risk and what it would cost to close it. A defensible partial claim beats an undefendable total one.
- What makes partitioning flags into independent groups the risky move?Independence is an assumption. If two groups secretly interact, no configuration you generate ever exercises the pair, and the suite stays green because the case was never created — an invisible gap rather than a failing test. It needs a named owner, a written rationale, and a re-check whenever a flag is added or moved between groups.
saying these in an interview costs you the question
- Optimises the generator instead of shrinking the space
- Promises exhaustive coverage while quietly sampling
- Assumes flags are independent without checking
- Treats a billion configurations as merely slow
- Never questions why thirty flags exist