Skip to content

Default Values

Every GrowthBook Feature has two layers of value resolution:

  1. Override rules — conditions, percentage rollouts, or experiment assignments you configure per environment. When a rule matches the current user context, it wins.
  2. Default value — the value returned when no rule matches. This is your safe floor.

When GrowthBook is completely unreachable (network error, CDN outage), the SDK falls back to the fallback argument you pass directly in your code — it never returns null or throws.

flowchart TD
  call["SDK call"] --> loaded{"GrowthBook loaded?"}
  loaded -- "YES" --> rules["Evaluate rules"]
  loaded -- "NO" --> fb["Return the fallback argument from your code"]
  rules --> match{"Match found?"}
  match -- "Yes" --> rv["Return rule value"]
  match -- "No match" --> dv["Return Feature default value"]
The three fallback layers
// BAD — if GrowthBook is unreachable, getFeatureValue returns undefined
const text = gb.getFeatureValue('banner-text');
// GOOD — safe fallback keeps the app working
const text = gb.getFeatureValue('banner-text', 'Welcome');

The fallback argument is the last line of defence. It should represent the experience you want users to have if GrowthBook is down — usually the current, stable behaviour.

  1. Open a Feature in the GrowthBook UI.
  2. Click Edit next to the Default Value field.
  3. Enter the value, e.g. Welcome for a string flag.
  4. Click Save.

The default value takes effect immediately for all environments where no override rule produces a match.

To update a default value without adding a rule:

  1. Open the Feature.
  2. Click Edit on the Default Value.
  3. Change the value and click Save.

The change is applied globally across every environment that does not have an overriding rule. No deploy required.

import { GrowthBook } from '@growthbook/growthbook';
const gb = new GrowthBook({
apiHost: 'https://cdn.growthbook.io',
clientKey: process.env.GROWTHBOOK_CLIENT_KEY,
attributes: {
id: 'user-123',
country: 'TH',
},
});
await gb.init({ timeout: 2000 });
// Returns the GrowthBook default value when no rule matches,
// or 'Welcome' when GrowthBook cannot be reached.
const bannerText = gb.getFeatureValue('banner-text', 'Welcome');
document.getElementById('banner').textContent = bannerText;
import { GrowthBook } from '@growthbook/growthbook';

const gb = new GrowthBook({
  apiHost: 'https://cdn.growthbook.io',
  clientKey: process.env.GROWTHBOOK_CLIENT_KEY,
  attributes: {
    id: 'user-123',
    country: 'TH',
  },
});

await gb.init({ timeout: 2000 });

// Safe fallback: 'Welcome' is used only if GrowthBook
// cannot be reached at all.
const bannerText = gb.getFeatureValue('banner-text', 'Welcome');

document.getElementById('banner').textContent = bannerText;
OptionBenefitCost
Safe fallback default valueThe app doesn’t break even if the SDK failsThe feature may look less complete during fallback
Default matching the new experienceCloser to what you intendedRisky if the SDK fails and you have to rely on this default
  • Setting the default value to “on” for a risky feature (it should always be a safe fallback)
  • Not testing that the app behaves correctly when the SDK cannot connect and falls back to the default
  • Forgetting that the default value is different from “the value set in the UI”

💡 Real-world example

Feature-flagging systems at large scale are commonly designed so the default is always “safe” when the config service is down, so the whole app doesn’t crash.

What value does the SDK return when a Feature exists in GrowthBook but no override rule matches?
What value does the SDK return when GrowthBook cannot be reached at all?
Which SDK call is MISSING a safe fallback and could return undefined?
What should the fallback argument represent?