Free — no signup required

Configuration Precedence: The Hierarchy of Truth

2 min read

Where Does Configuration Come From?

A robust tool often needs configuration beyond what users type on the command line: API keys, default regions, timeout values, log levels. Users should be able to set these in multiple ways depending on their context — a developer might set a default in a config file, while a CI/CD pipeline sets it via an environment variable, and an operator overrides it at runtime with a flag.

The standard hierarchy of precedence, from lowest priority to highest, is:

1. Default Values          (hardcoded in the application)
2. Configuration File      (~/.mytool/config.yaml or /etc/mytool/config.yaml)
3. Environment Variables   (MYTOOL_TIMEOUT=120)
4. Command Line Flags      (--timeout=10)

The Rule: Flags always win. If a user explicitly types --timeout=10, they don't care what the config file says. Environment variables override config files because they represent the deployment environment's intent. Config files override defaults because the user has explicitly chosen a preference.

This hierarchy follows the 12-Factor App methodology (Factor III: Config), which states that configuration that varies between deployments should be stored in environment variables. This makes your tool portable across environments without modifying files.

Practical Implementation:

import os
import argparse

# 1. Start with defaults
config = {"timeout": 30, "region": "us-east-1"}

# 2. Override with environment variables
if os.environ.get("MYTOOL_TIMEOUT"):
    config["timeout"] = int(os.environ["MYTOOL_TIMEOUT"])
if os.environ.get("MYTOOL_REGION"):
    config["region"] = os.environ["MYTOOL_REGION"]

# 3. Override with CLI flags (highest priority)
parser = argparse.ArgumentParser()
parser.add_argument("--timeout", type=int, default=None)
parser.add_argument("--region", default=None)
args = parser.parse_args()

if args.timeout is not None:
    config["timeout"] = args.timeout
if args.region is not None:
    config["region"] = args.region

A senior engineer also considers where to document this hierarchy. The --help output should mention which environment variables the tool respects, so users don't have to read source code to discover them.

This is one of 18 chapters

Every chapter is free — Kubernetes, Terraform, SRE, distributed systems, and more — with fast daily review built in.

Sign up free