The resolution algorithm
When you query a feature, Foff walks the hierarchy from the most specific combination of values down to the least specific, checking for an override at each step. The first match wins. If no override matches any level, Foff returns the feature’s default value. For a hierarchy of[level-1, level-2, level-3], the resolution order is:
level-1+level-2+level-3(full path — most specific)level-1+level-2level-1- (feature default) (least specific — always the final fallback)
Step-by-step example
Suppose your scope uses the hierarchyOrganization → Team → User. Your application fetches dark-mode for the values ["org-1", "team-a", "user-123"].
Step 1: Check org-1 + team-a + user-123
Step 1: Check org-1 + team-a + user-123
Foff looks for an override scoped to exactly
org-1, team-a, and user-123. This would be a user-specific override — the most granular possible. If found, this value is returned immediately and resolution stops.Step 2: Check org-1 + team-a
Step 2: Check org-1 + team-a
No user-level override was found. Foff checks for a team-level override scoped to
org-1 and team-a. If an override exists here, it applies to every user in that team (unless they have a user-specific override). If found, this value is returned and resolution stops.Step 3: Check org-1
Step 3: Check org-1
No team-level override was found. Foff checks for an organization-level override scoped to
org-1. If found, this applies to every user in the organization who doesn’t have a more specific override. If found, this value is returned and resolution stops.Step 4: Return the feature default
Step 4: Return the feature default
No organization-level override was found. Foff returns the feature’s default value — the one you set when you created the feature. This is the ultimate fallback and always applies when no override matches.
Why this model is powerful
The hierarchy model means you write your flag logic once and Foff handles the targeting automatically. Consider what this enables:- Roll out to one org: Add an override at
org-1to enable a feature for every user in that organization — without touching any other org. - Exclude one team: Add an override at
org-1 + team-athat disables a feature, even if the org-level override enables it for everyone else. - Target a single user: Add an override at
org-1 + team-a + user-123to give one user a different experience without affecting anyone else.
Reference: resolution order table
| Step | Hierarchy path | Description |
|---|---|---|
| 1 | All levels combined | Most specific — exact match for this entity |
| 2 | All levels except the last | Parent-level override |
| … | … | Continues up the hierarchy |
| N | First level only | Top-level organization override |
| N+1 | (none) | Feature default — always the final fallback |
Related concepts
Overrides
Learn how to create overrides and what values you can set at each hierarchy level.
Scopes
Understand how scopes define the hierarchy model for a group of flags.