A staging environment that is meaningfully different from production is a staging environment that lies. We stopped using one of those after 2019. The current rule: staging runs the same code, the same Postgres major version, the same Node runtime, and the same edge configuration as production — only the data is different and the secrets are scoped.
The data difference is the hard part. We use a nightly anonymised replica of production, with PII scrubbed at the column level by a script that lives in the same repo as the application. If the production schema changes without the scrub script changing, the build breaks. That is the point.
The benefit is enormous. A regression that would have shipped to production gets caught on staging on a Tuesday afternoon, with a screenshot, by the engineer who wrote the change. The Friday-night incident becomes a Tuesday-afternoon pull-request comment.
The cost is one engineer-week per quarter to keep the parity intact. We bill it transparently as part of the retainer. Clients sometimes question it. We have never had a client question it twice.