Infrastructure

Detecting Magento Environment Drift Before It Bites

Staging only predicts production when they match. Detect config, code, and schema drift between environments before a deploy turns a hidden gap into an outage.

Jason Schuman · June 10, 2026

Staging only tells the truth if it matches production

Teams trust staging to predict what a deploy will do in production. That trust is only earned when the two environments actually match, in code, configuration, and database schema.

When they drift apart, staging tests pass and production still breaks. The gap between them is where a surprising number of "but we tested this" incidents actually come from.

This article covers the three kinds of drift, how each one happens, and how to detect them before a deploy turns a hidden difference into an outage.

Three kinds of drift

Environment drift is not one problem. It is three, and they hide in different places:

  • Config drift, where settings in the production admin no longer match staging or version control.
  • Code drift, where files on production differ from what is committed to git.
  • Schema drift, where the production database structure no longer matches what the code expects.

Each has its own cause and its own detection method. Treating them as one thing is a large part of why they go unnoticed.

Config drift: the admin is a backdoor around version control

Magento stores most configuration in the core_config_data table, editable from the admin. Every value changed there in production, and not mirrored to staging, is config drift.

The defense is app/etc/config.php. Running bin/magento app:config:dump exports configuration into that file, where it can be committed, reviewed, and applied identically across environments.

To find existing drift, dump config from each environment and diff the results. The differences are the settings someone changed in one place and nowhere else.

Any setting the store relies on that lives only in one environment's database is drift. If it is not in config.php or version control, the next deploy may not know it exists.

Code drift: hotfixes that live only on production

Code drift is a change made directly on the production server that never made it back into git. The classic case is an urgent fix edited straight into a file during an incident.

It works until the next deploy overwrites it, at which point the bug returns with no obvious cause, because the fix never existed anywhere the deploy could see. Hand-edited files inside vendor/ are the most dangerous version of this.

If production is deployed from git, git status on the server surfaces untracked and modified files immediately. For vendor code, a diff against a clean install of the same version is the reliable check.

Schema drift: manual SQL and half-run upgrades

Schema drift happens when the production database structure diverges from what the module code declares. Two things cause it: manual SQL run directly against production, and a setup:upgrade that failed partway.

Magento can tell you when the schema is behind the code. bin/magento setup:db:status reports whether the database matches the declared schema and whether an upgrade is pending.

A store that reports the schema out of date, or that carries custom tables and columns no module declares, has drift that will complicate the next upgrade.

config.php and env.php do different jobs

Managing config drift means understanding the two files Magento splits configuration across. app/etc/config.php holds shared configuration that is the same everywhere and belongs in version control.

The app/etc/env.php file holds environment-specific values: database credentials, cache backends, and the encryption key. It is different in every environment by design and should not be committed.

Drift hides when a value that belongs in config.php is left only in the database, or when someone edits env.php on production and records nowhere why. Keep that split clean and most config drift simply stops happening.

env.php also carries the encryption key. That is why copying a production database to staging without also matching the key leaves staging unable to decrypt stored credentials, which is a drift problem people usually discover at the worst moment.

How to detect all three quickly

A drift check does not take long once you know where to look. Run each of these against production and compare to staging and to git:

  • bin/magento app:config:dump, then diff the resulting config.php between environments.
  • git status plus a vendor diff against a clean install, to catch code drift.
  • bin/magento setup:db:status, to catch pending or mismatched schema.

What those three surface is your drift inventory. Most of it will be config, some will be code, and the schema findings tend to be the ones that most complicate an upgrade.

Closing the gap and keeping it closed

Detecting drift once is useful. Preventing it is what makes staging trustworthy again.

The habit that closes the gap is simple. Configuration goes through config.php and version control, not the production admin, and no code or SQL touches production outside a deploy. Knowing where your environments currently disagree is the first step, and it is exactly what a structured review measures before anyone plans an upgrade.