NOTE · 13 OCTOBER 2026

Make staging tell the truth about production

Why a staging environment that drifts from production makes every release a guess, and the order in which we close the differences.

A staging environment has one job: to tell you what production will do with a change before production does it. When staging was built by hand, patched by whoever needed it and never rebuilt, it stops doing that job. Releases pass in staging and fail in production, the team learns to distrust staging, and the real test moves to the moment of release.

Where the differences hide

The drift usually sits in three places. Configuration: environment variables, feature flags, secrets and service limits that were changed in one place and not the other. Data: staging holds a few tidy records while production holds years of edge cases. And the deploy path itself: production is released by a person following steps, staging by a script someone wrote once.

Each of those produces a different kind of surprise. Configuration drift gives errors that make no sense until someone compares the two environments line by line. Data drift gives slow queries and broken migrations. A different deploy path means staging never exercised the steps that fail.

The order we close them

We start with the deploy path, because it is the cheapest to fix and it makes every other fix stick. One pipeline, written as code, deploys to every environment with the same steps; only the target and its inputs differ. Once that exists, a difference between environments has to be declared somewhere a reviewer can see it.

Then configuration. We write the infrastructure and the settings for the chosen service as code and generate each environment from it. The differences that must remain, such as size, scale and external endpoints, become explicit parameters instead of accidents.

Data comes last and needs the most care, because production data is usually personal data. The aim is representative shape, not a copy: the same volume range, the same awkward records, the same migrations, produced from generated or masked data under rules the data owner has approved.

What good looks like

A good staging environment is boring. It can be destroyed and rebuilt from the repository, a release behaves there the way it then behaves in production, and when it does not, the difference shows up in a reviewed change rather than in a late night investigation. Rollback has been rehearsed there, so the first time it runs in production is not the first time it has run at all.

We do this for one service first, the one that changes most often, and let the result argue for the rest. Moving everything at once turns a repair into a migration, and migrations are where new drift is born.

SOURCES

Where the facts come from

This note is about method. It states no outside facts, so it cites no sources.

Talk it through with us

Send a short description of your system and the question this note raised. We reply with how we would approach it in your setup.

Start a conversation