OneEnv
← All posts🌊 Concept

What Is Configuration Drift in Microservices?

ShareLinkedInX

Configuration drift is when the same logical setting holds different values in places that are supposed to agree. It is rarely dramatic. It is a timeout that is 30 seconds in three services and 5 in the fourth, a feature flag enabled in the API but not the worker, a base URL that was updated everywhere except the one cron container nobody remembers. This article explains why it happens, how to find it, and what actually reduces it, whether or not you use OneEnv.

Why drift happens

  • Copies, not references. Each service has its own .env, Helm values file or secret. A change means N edits, and N is eventually remembered as N-1.
  • Different change paths. One service deploys from a pipeline variable, another reads a mounted file, a third has a default baked into code. There is no single place to look.
  • Temporary fixes that stay. An incident override is applied by hand and never rolled back.
  • No record of dependency. Nobody can list which services read PAYMENTS_BASE_URL, so nobody knows the full set to update.

A concrete example

Four services call the payments API: web, mobile-bff, invoicer and refunder. The payments team moves the API to a new host and tells the channel. Three owners update their config. refunder runs only on the first of the month, so the failure shows up three weeks later, during a billing run, as a connection error with no obvious link to a change nobody remembers.

How to detect it

Start with an inventory: for each shared key, the value each service actually receives. If your services are configured through files in Git, a script is enough:

Find keys whose values disagree across service env files (illustrative; adapt paths)
for key in PAYMENTS_BASE_URL REQUEST_TIMEOUT_MS; do
  echo "== $key"
  grep -H "^$key=" services/*/.env.production | sed 's#services/##; s#/.env.production:# #'
done

If the values live in a platform (CI variables, a secret store, Kubernetes ConfigMaps), the same idea applies via that platform's API. The harder question is intent: a difference is drift only if the values were supposed to match. That is information the files do not contain, which is why recording the dependency matters as much as comparing values.

What reduces drift

  • One source per shared value. Services reference it instead of copying it.
  • An explicit consumer list. So a change can name everyone it affects.
  • A reviewed change path. The same path for every service, with a record.
  • A scheduled comparison. A job that fails when values that should match differ. Cheap, and it catches what process misses.
  • Expiring overrides. Any manual override gets an owner and a date.

Trade-offs

  • A single source becomes a dependency and a place where one bad edit has wide reach, which is the reason to review it.
  • Forcing every service onto one value removes legitimate differences. Allow explicit, visible overrides rather than banning them.
  • Tooling cannot tell you which differences are intentional. Someone has to say.
Where OneEnv fits (and where it does not)
OneEnv records which services inherit a shared value, stages edits on a branch, and asks each consuming service to approve a change, so a drift caused by 'we forgot service four' becomes a visible pending decision instead of a silent gap. A service that rejects keeps its last approved value on purpose and is shown as diverged. OneEnv does not inspect your running systems, so it cannot detect drift between its records and what is deployed. See Environment variable governance and the hands-on five-services tutorial.
ShareLinkedInX