Skip to content

---

title: What to move into config first: a checklist

slug: config-checklist

lang: en

published: 2026-11-07

words: 427

lines: 67

size: 2.4 KB

read: 3 min read

---

What to move into config first: a checklist

The corner shop puts a new price sticker on every can. The big store keeps the price in one system, and every till reads it from there. In code, that system is config: a value is written in one place, and the rest of the code reads it from there.

This is the order I move values out of code, with real examples from the config of this site.

1. Secrets, before anything else

Passwords, API keys and signing keys never sit in code or in a YAML file. The YAML only names the environment variable, and startup fails when it is missing:

yaml
django:
  secret_key: ${DJANGO_SECRET_KEY}
database:
  url: ${DATABASE_URL}

2. Anything that changes between machines

Domains, URLs, hosts and the storage backend are different on your laptop and on the server. Give them a default only when the default is safe:

yaml
app:
  site_url: ${SITE_URL}
storage:
  backend: ${STORAGE_BACKEND:-local}

3. Limits and timeouts

Retries, timeouts, upload sizes and rate limits are the numbers you end up tuning. Put the unit in the key name, so nobody guesses whether 10 means seconds or minutes:

yaml
auth:
  access_token_minutes: 15
  login_failures_limit: 5
  login_window_minutes: 15
uploads:
  video:
    max_mb_s3: 300

4. Values one file writes and another reads

If the same number appears in two places, one of them will be forgotten. That is the sticker the shop missed. Write it once and let both read it.

5. Product knobs

Cache windows, how many items a page shows, feature switches. Change them without touching logic:

yaml
api:
  revalidate_seconds: 60

Three rules that keep config honest

  • Validate it. My schema is strict: an unknown or missing key stops startup with its path in the message. A typo fails loudly instead of silently using a default.
  • One loader. Only the config loader reads the environment. The rest of the code gets a typed config object.
  • One base, small overrides. base.yaml holds everything; production.yaml overrides only what differs, such as turning the API docs off.

What stays in code

Not every number is config. A value that never changes and only makes sense next to its logic, such as the number of days in a week, stays a named constant in code. Config is for the numbers you will change.

Check your repo

Search your code for numbers and strings that look like settings. Every hit is a sticker on a can. Move it to config, give it a clear name with its unit, and read it from one place.

en3 min read