Environment
Stage
A separate place to run the same code — development, staging, production — so a change can be checked in stages before it reaches users.
Why it exists
When a service ran on a single server, changing the code meant pushing it straight to that server, because there was nowhere else to check it. If it worked, fine. If it broke, the first person to find out was whoever happened to be looking at the screen.
That is how deploys became a late-night activity. Pick the hour with the fewest people online, push, roll back fast if it breaks, and reconstruct in the morning what actually happened. On the day the checkout page changed, someone stayed at the office refreshing the orders dashboard to see whether the usual number of purchases was still coming through. A sudden drop was the signal to revert.
The underlying problem was that the place you verified in and the place users lived in were the same place. An environment is the line drawn between those two. You keep a space that no user can reach, run the same code there first, and let only what survives move forward. The cost of a mistake shifts from the users to the team.
What this stage looks like
The baseline is three stages. Development, staging, production — in that order, each one closer to real users than the last.
- Development — the space each person building the software works in, usually their own laptop, filled with data they made up themselves. You can restart the server twenty times and nothing happens. Being safe to break is the whole value of this stage.
- Staging — a rehearsal space set up to resemble production as closely as it can. The server topology and the outside services it connects to are matched, and instead of real users the team goes in and clicks through. Anything involving money is pointed at the test endpoint the payment provider hands out, so no actual charge occurs.
- Production — where real users arrive. Real data accumulates and real payments happen. This is the only stage where access is restricted person by person. Anyone on the team can get into development, while the list of people who can query production data directly is usually kept to two or three.
Four things separate the stages: who can get in, what data sits inside, how much capacity it has, and what you lose when something goes wrong. The first two can usually be matched to the original fairly well. Capacity cannot. A service running on twelve servers in production is often staged on two, because a second always-on copy adds its cost every hour of every day.
What moves you to the next one
Moving from one stage to the next means passing a gate. There are two of them.
- Development to staging — someone else reads the change and approves it, and every automated test passes. Then the build has to succeed. A build turns code written for humans to read into a form a machine can execute, and the bundle that comes out of it is called an artifact.
- Staging to production — a person goes in, clicks through the important screens, and decides based on what they saw. The path from signup to checkout is written down in advance and walked exactly as written.
The rule when moving between stages is that you do not rebuild. The artifact verified in staging is the artifact that goes to production. Rebuild at each stage and the thing you checked stops being the thing you shipped, which makes passing staging a guarantee of nothing.
That leaves the parts that genuinely have to behave differently per stage. Those live in environment variables — which database address to talk to, whether to hit the payment sandbox or the real endpoint — injected from outside the code. The values that must never leak are handled separately through secret management, kept in a vault and pulled out only at the moment of execution.
Drift between stages appears on its own over time. Someone changes a server setting in production under pressure and never mirrors it to staging. Writing the server configuration down as infrastructure as code (IaC) narrows the gap, because all three stages then get built from the same file.
How it sounds at work
"It works locally but it fails in production."
There's a configuration or version difference between the laptop and the production server, and finding that difference is the next task.
"Push that to staging first. I'll go through it tomorrow morning."
A request not to send it to users yet, and to leave time for a look.
"Staging has drifted pretty far from production, so passing there doesn't tell us much right now."
The rehearsal space no longer resembles the original, so it has stopped functioning as a gate and needs to be brought back in line.
At Pagedeck a new feature rides a pipeline through all three stages in order. When Theo merges, the machine runs the build and the tests, and the artifact that passes lands on staging. Mia and Noa open that address, click through the screens, and note anything with awkward copy or behavior that doesn't match. Problems caught here never reach a user.
The decision to move to production comes after the staging pass is done. If the feature touches enterprise accounts, Sofia sometimes asks for a day or two so she can notify customers first. Even then nothing is rebuilt — the same artifact that sat on staging is the one that goes up.
What people get wrong
The most common belief is that passing staging means production will behave the same way. Since the two were deliberately matched, that expectation is reasonable. But what gets matched is configuration, not scale and not data. If staging holds 200 records and production holds 2 million, a list screen that renders in 0.1 seconds in staging can take 8 seconds in production. Ship without knowing that and users find the problem first, and the feature spends the rollback window flickering on and off.
Treating environments as a question of server count is the other one. In that view, staging just needs to be one instance running somewhere. But what divides environments is data and access, not hardware. Split a single server into folders and call it two stages, and code still under development can reach production data. That is where most of the real accidents happen — a cleanup script run as an experiment turns out to have been pointed at the production database.
Easily confused with
| Term | What it is | How it differs |
|---|---|---|
| Environment variable | A configuration value injected from outside the code at run time | An environment is a space; an environment variable is a value that changes per space. Three environments means three copies of the same named variable |
Where to go next
Related terms
Last updated 2026-09-16