how-to

Feature Flags vs Config Files - When to Use Which (2026)

Config files and feature flags both control behavior without a code change, but they solve different problems. Here's how to tell them apart, and when a flag service beats a config file.

Published:

Both a config file and a feature flag let you change how software behaves without editing code. That’s why people confuse them. And it’s why teams sometimes reach for the wrong one - shipping a redeploy for something that should have been a runtime flip, or wiring up a whole flag service for a setting that never changes.

They solve different problems. A config file changes with a deploy. A feature flag changes while the app is running. That one difference decides almost everything. This guide walks through where each belongs, and when a config file stops being enough.

What a config file is good at

A config file holds settings that are scoped to a deploy and an environment. Database URLs. Timeouts. Log levels. Third-party API endpoints. The environment name. Build constants.

These share three traits. They change rarely. They apply to the whole app, not a subset of users. And they’re naturally tied to a release - you don’t change your production database host at 2pm on a Tuesday without a deploy, and you wouldn’t want to.

For that kind of setting, a config file is simpler and correct. If it’s environment-level, rarely changes, and never needs per-user targeting, it belongs in config. Adding a flag service for it is pure overhead.

What a feature flag is good at

A feature flag is a switch you control at runtime, without a deploy, often for a slice of users.

That unlocks things a config file can’t do:

  • Flip without a deploy. Turn a feature on or off from a dashboard in seconds, no release in the loop.
  • Target a subset. Roll a feature out to 1% of users, or to internal staff, or to one region.
  • Kill switch. When something breaks, flip it off instantly instead of rolling back a deploy.
  • Audit trail. See who changed what flag, when, and why.

None of those are a config file’s job. The moment you need one of them, you’ve outgrown the file.

The line: does it change while the app runs?

Here’s the clean test. Ask one question of any setting: does it need to change while the app is running, without a deploy?

If no, it’s config. Ship it in the file. If yes, it’s a flag. It belongs in a flag service.

A permanent architecture choice - which payment provider you use, your database connection string - is config, because it changes with a deliberate release or never. A release you want to roll out gradually, or kill instantly if it misbehaves, is a flag, because the whole value is changing it live.

The trap: config files pretending to be flags

The failure mode is using a config file as a crude flag. A boolean in a YAML file, redeployed every time you want to flip it.

It works for the first few. Then it breaks. You can’t roll out to 10% of users from a boolean. You can’t flip it without a deploy, so your “kill switch” takes a full release to fire - useless in an incident. There’s no audit trail. And as the number of these grows, your config file becomes a pile of half-documented toggles nobody dares touch.

The redeploy is the tell. If you’re shipping a deploy just to change a value, that value wanted to be a flag.

When you cross the line: which flag tool

Once you’ve decided something is a flag, you need somewhere to store and serve it - and this is where flag state must live outside your build. If flag values sit in a file you redeploy to change, you’ve reinvented the config file and lost the runtime benefit. Flag state belongs in a service every running instance reads live.

Three options, by what you’re optimizing for:

Depth, if you can absorb the cost. LaunchDarkly is the deepest option - advanced targeting rules, guarded releases that automatically roll back on a bad metric, around 38 SDKs. The trade is its pricing: $10 per service connection per month plus $8.33 per 1,000 client-side monthly active users, charged on your highest-volume context kind, which surprises teams that estimate from headcount. Model your real context volume first.

Flat, predictable pricing. ConfigCat is the closest thing to a config file with runtime superpowers, and its pricing fits the mental model. It charges no per-seat and no per-MAU fee - MAUs, contexts and flag reads are unlimited on every tier - and you pay by config-download volume instead. Forever Free gives 10 flags and 5M downloads a month; Pro is $110. The one thing to watch, fittingly, is polling: a chatty SDK can push you across a download tier without adding a single user, so cache aggressively and use the SDK proxy.

Self-hosting in your own infra. Unleash is the strongest open-source pick - AGPL-3.0, self-hostable including air-gapped, with activation strategies, gradual rollouts and kill switches in the free edition. The gotcha: RBAC, SSO/SAML and SCIM are all Enterprise-gated, and there’s no read-only viewer seat, so once non-engineers need access it’s $75 per seat per month with a 5-seat minimum.

Use both, on purpose

The answer isn’t flags instead of config. Mature systems run both, deliberately.

Config files hold the deploy-scoped, environment-level settings that rarely change - connection strings, endpoints, build constants. Feature flags hold the runtime decisions that change often, target users, and need instant reversal - new features, experiments, kill switches.

The skill is knowing which layer a setting belongs in. Put a runtime decision in config and you’ll redeploy for every change. Put an environment constant behind a flag service and you’ve added a network dependency and a bill for nothing.

So which is it?

  • Environment-level, rarely changes, no targeting - config file. Keep it simple.
  • Runtime change, targeting, gradual rollout, or a kill switch - feature flag. Use a service, not a file.
  • You want depth and can forecast the cost - LaunchDarkly.
  • You want flat, headcount-independent pricing - ConfigCat, and watch your polling.
  • You want to self-host in your own infra - Unleash, if you can live inside the open-source feature set.

Ask the one question - does it change while the app is running - and the answer falls out. Config for the deploy-time constants, flags for the runtime decisions, and never a redeploy for something that should have been a switch.


Tool pricing and features verified against each vendor’s site on 26 July 2026. Feature-flag pricing changes often - we re-verify regularly. LaunchDarkly contract figures cited elsewhere are from Vendr’s third-party buyer data and attributed as such.

Frequently Asked Questions

What's the difference between a feature flag and a config file?

A config file holds settings that change with a deploy - database URLs, timeouts, environment names. A feature flag is a switch you can flip at runtime, without a deploy, often for a subset of users. Both change behavior without editing code, but the config file needs a release to take effect, while the flag changes instantly from a dashboard or API. If you need to change it while the app is running, it's a flag's job.

Can't I just use a config file as a feature flag?

You can for the simplest cases - a boolean in a config file that you redeploy to change is a crude flag. It breaks down fast, though. You can't target a percentage of users, you can't flip it without a deploy, you have no audit trail, and there's no instant kill switch when something breaks. The moment you need runtime changes, per-user targeting, or gradual rollouts, a config file stops being enough and a flag service earns its place.

Do feature flags replace config files?

No, they complement each other. Config files still handle deploy-time, environment-level settings that rarely change and don't need targeting - connection strings, feature toggles that are permanent architecture choices, build constants. Feature flags handle runtime decisions that change often, target users, and need instant reversal. Most mature systems use both, and the skill is knowing which layer a given setting belongs in.

When is a config file better than a feature flag?

When the setting is environment-level, rarely changes, and never needs per-user targeting or runtime flipping - database hosts, log levels, third-party API endpoints, static build constants. These belong in config because they're deploy-scoped by nature and adding a flag service for them is pure overhead. Reach for a flag only when you need runtime control, targeting, or gradual rollout. Otherwise the config file is simpler and correct.

Explore More

Free Newsletter

Get the Feature Flags Newsletter

Platform benchmarks, real pricing data and progressive delivery practice. No spam.

Free. Unsubscribe any time. See our privacy policy.

Related Articles