Home › Guides › Catching Config Drift: Using a Diff to Find Out Why Staging Works and Production Doesn't

Catching Config Drift: Using a Diff to Find Out Why Staging Works and Production Doesn't

By Mohak Mangal · Published October 26, 2026 · 6 min read

"It works on staging." Every developer has said it, and every operations person has groaned. Usually the answer isn't the code. It's a setting that's different between the two environments, and nobody noticed because nobody looked. A diff is the fastest way to look.

What to compare

  • Configuration files such as nginx or Apache configs, php.ini, application settings.
  • Environment variable lists. Export the names (and for non-secret ones, values) from both environments and compare.
  • Package lists. Output of pip freeze, npm ls --depth=0 or dpkg -l. A single minor version difference can explain odd behaviour.
  • Database schema dumps, without data.
  • DNS records or firewall rules exported as text.

A word of caution on secrets: never paste passwords, API keys or tokens into any tool you don't fully control. Strip or mask them first. A diff that runs locally in your browser, like ours, doesn't upload what you paste, but good habits still beat good luck.

Clean the input first

Raw output is noisy, and noise buries real differences. Before comparing:

  1. Sort the lines when order doesn't matter (sort file.txt). Environment variables and package lists are the obvious cases.
  2. Remove comments and blank lines if you only care about live settings: grep -v '^\s*#' file | grep -v '^\s*$'.
  3. Normalise whitespace. Use the ignore-whitespace option so trailing spaces and tab/space mixups don't light up every line.
  4. Remove volatile values like timestamps and generated IDs, which always differ.

A worked mini-example

Say production's list of environment variable names has CACHE_DRIVER, QUEUE_CONNECTION and APP_DEBUG, while staging has CACHE_DRIVER, APP_DEBUG and MAIL_HOST. A diff of the sorted lists reports two lines: QUEUE_CONNECTION present only in production, and MAIL_HOST present only in staging. In two seconds you've learned that production has a queue setting staging lacks (so background jobs behave differently in testing) and that staging sends mail through a host that production doesn't define. That's the sort of discovery that otherwise takes an afternoon.

Reading a diff with a clear head

  • Lines marked removed exist only in the first text. Lines marked added exist only in the second.
  • A changed value appears as one removal plus one addition next to each other.
  • Don't assume every difference is a problem. Debug flags, hostnames and resource limits are supposed to differ. Make a short list of intentional differences so you can ignore them next time.

Turn it into a habit, not a rescue

The better approach is to check for drift before something breaks. After any release that touches configuration, export and compare. If your team uses infrastructure-as-code, the code itself is the source of truth, and a diff against the live system tells you if someone made a manual change. Those undocumented hotfixes are the usual source of "mystery" differences.

For prose and documents

The same technique helps when two people have edited a document. Paste each version, turn on ignore-case if capitalisation is just noise, and read only the highlighted lines. For long paragraphs, put each sentence on its own line first, or a single changed word will highlight the whole paragraph.

When you're ready to try it, the text difference checker works entirely in your browser. Whatever you compare, you'll find the most valuable lines are the ones you didn't know were different.

Free tool
Try it now: Text Difference Checker
Compare two blocks of text line by line and see exactly what was added or removed.

Keep reading