Separate copies of the product for different purposes: a developer's laptop, a staging rehearsal, and production where real users are.
Why it exists
Testing risky changes on the live product would break it for real users, but you still need somewhere realistic to try them. Environments exist as separate copies, local, staging, and production, so work can be built and verified safely before it reaches customers.
How it actually works
Code moves through stages. Local is the engineer's own machine. Staging is a shared copy that mirrors production, where changes are tested safely with fake or copied data. Production is the real thing, with real users and real money.
Keeping them separate means changes are tried and proven before they ever touch users. "Test it in staging first" is this discipline.
A senior PM walks you through it
A junior PM, stuck
Customers kept failing at payment during Friday's lunch rush, so I filed a bug. The dev closed it an hour later with one line, "works fine on staging", and production customers are still failing. I know staging and production are different somehow, but I cannot say how, so I have no grounds to reopen the ticket.
That one line is not a lie, it is just not an answer, and the reason lives in two small files. Below are the actual .env files the staging and production copies of TiffinBox read at startup, side by side, with only the live payment key masked. Everything that separates "works on staging" from "works for customers" is in the lines that do not match. Five minutes of reading and you can reopen that ticket with a reason.
The .env files staging and production read at startup, live key masked
Accepting "works fine on staging" as closure on a production bug. It proves the staging combination of settings works; your ticket is about production's combination, so it stays open until someone reproduces with production's flag and gateway.
Demoing a feature on staging and telling stakeholders it is live. A flag can be on in staging and off in production, so the room just saw something customers cannot see yet.
Filing a payment bug without naming the environment. A sandbox failure moves no money and a live one does, so devs triage them differently; name the environment in the first line of the ticket.
Asking for the production .env to be pasted into a ticket so you can compare. The live key is a secret; ask "which settings differ between staging and prod for checkout" and let the dev answer in words.
Reopen the ticket with: "Staging runs the new checkout flag on, against the sandbox gateway and a copied database. Production runs the flag off against the live gateway, which is where customers are failing. Can you retest with production's combination?" You read two config files, found the lines that differ, and turned a closed ticket into a precise retest.
Where a PM meets this
"Can you demo it?" usually means on staging; "is it live?" means in production. The distinction avoids confusion.
Staging that doesn't match production causes "worked in staging, broke live" bugs; asking "how close is staging to prod?" is worthwhile.
Hear it in a meeting
"It's on staging now, ship to production after we verify."