ON THIS PAGE (7 SECTIONS)
- ✓Twelve-factor config is what varies between deploys: resource handles, credentials, and hostnames. Code does not.
- ✓The litmus test is whether the repo could be published without a credential in it.
- ✓Named environment blocks explode into one-off copies. Prefer values set per deploy.
- ✓A behavior flag that exists only in production is untested code.
Staging talks to a sandbox payments host. Production talks to the live one. That difference belongs in configuration. A second difference, an if statement that skips fraud checks when the hostname contains "staging," does not. The build you tested is not the build you run, even though the git tag matches.
The twelve-factor config chapter draws the line clearly. Config is everything that varies between deploys: database handles, credentials, the canonical hostname. Internal wiring that does not vary belongs in code. The test Adam Wiggins gives is whether you could open-source the repository at any moment without compromising a credential. Grouping values into ever more named environments, including someone’s personal staging, is how the matrix becomes impossible to reason about. Set the values for each deploy. Do not invent a new environment name for each combination.
What may differ, and what should not
| May differ per deploy | Should be the same code path |
| Database URL, bucket name, queue name | The queries and the job handlers |
| Credentials | The calls those credentials authorize |
| Log volume and sample rate | Which events exist |
| Feature flags you operate on purpose | A branch that runs only when a hostname matches |
| The model name, if you meant to test that model | A prompt that production edits outside review |
Secrets follow Keep Secrets Out of the Client and the Repo. Flags that change model or prompt behavior follow Feature Flags for AI, and they are still configuration you can name, not a fork. A prompt edited in a production console and nowhere else will not be what staging ran.
Illustrative scenario
This scenario is illustrative. One container image is built. Staging and production receive different environment values for the database, the public URL, and the payments host. The fraud check runs in both. Staging uses a test merchant account, which is a credential and a hostname, not a deleted function. A developer can run the same image locally with local values. Nothing in the image is a production password. If a check must be off, it is a flag with an owner and an expiry, visible in both environments’ config, not a condition on the URL.
Checklist
- List what is allowed to change between deploys.
- Fail startup when a required value is missing. Do not default a production host to localhost.
- Keep credentials out of the repo.
- Run the same artifact in staging and production.
- Review flags that differ. A permanent production-only branch is a second system.
- Do not add a new named environment for one customer if a value would do.
Questions that usually come next
Are config files worse than environment variables?
Twelve-factor prefers environment variables because they are less likely to be committed and they are not tied to one language. A file can be fine if it is not in git and you can see the whole set. The failure mode is the same: a secret or a behavior fork that only production has.
Should staging use less data?
It can use less data. It should not use different code. Volume differences hide some performance bugs. Code differences hide the bugs you are about to ship. Use a realistic path even when the dataset is smaller, and read query plans against a larger copy when the access path matters.
Direct answers
Are config files acceptable?
Yes, if they stay out of git and the set of values is visible. The mistake is a secret or a code path that exists only in production.
Can staging run a smaller dataset?
Yes. It should run the same artifact. Shrink data if you must. Do not delete code paths.
References & Prior Art
The Twelve-Factor App: Config
Adam Wiggins • Twelve-Factor (2017)
Naveen
Infrastructure EngineerNaveen handles infrastructure, edge network resilience, chunked media pipelines, and deterministic CI/CD release verification at Vasiva.