Notes from the terminal

Configuration without tears

backendOctober 3, 2026 · 6 min read

Configuration is the part of a project that nobody plans and everybody suffers from. It starts as a couple of constants at the top of a file and ends as three layers of overrides that no one can fully explain. These are the habits that have kept it manageable for me.

Keep the list short

Every setting is a decision somebody has to make and a way for the system to be wrong. Before adding a new option, ask whether a sensible default would do. Most options I have added over the years were never changed by anyone, including me.

One source of truth for defaults

Defaults should live in the code, in exactly one place, next to the code that uses them. The environment then overrides only what is different. When defaults are scattered across files, a deployment can quietly change behaviour without anyone noticing.

type Config struct {
    Port        int           `env:"PORT"          default:"8080"`
    DatabaseURL string        `env:"DATABASE_URL"  required:"true"`
    Timeout     time.Duration `env:"TIMEOUT"       default:"5s"`
}

Fail at startup

A service with a missing or invalid setting should refuse to start and say exactly why. The worst version of this problem is the one that appears three hours after a deploy, when some rarely used code path finally reads the broken value.

Print the effective configuration

When the service starts, log the final configuration, with secrets masked. It turns the question "what is it actually running with?" from an investigation into a glance at the logs.

Keep secrets out of the repository

This one is well known and still violated constantly. Secrets belong in the environment or in a dedicated secret store, and the repository should contain only a template with fake values so that a new developer knows what to provide.

Differences between environments should be small

The more production differs from staging, the less staging tells you. I try to keep the list of differences short enough to fit in a short paragraph, and I write that paragraph down.

Good configuration is invisible. You only notice it when it is missing.

← Back to all posts