Dev vs Staging vs Production in GCP

Dev, staging, and production are three separate environments with different purposes. Dev is where code gets built and tested quickly. Staging is where it gets validated under realistic conditions. Production is where it serves real users. Getting the differences right is what makes a CI/CD pipeline actually reliable.

What are dev, staging, and production?

Each environment is a full deployment of your application with its own infrastructure, configuration, and access rules. They share the same codebase but serve very different purposes.

  • Development (dev): where developers build and test features. It accepts unstable, frequent deployments and prioritises iteration speed over reliability.
  • Staging: a production-like environment used to validate a release before it reaches users. It should be close enough to production to catch realistic problems.
  • Production (prod): the live environment serving real users. Every change is deliberate and controlled.

The purpose of separating these environments is blast radius reduction: keeping the consequences of a mistake contained to an environment where mistakes do not matter. A broken dev deployment is a developer problem. A broken staging deployment is a quality gate doing its job. A broken production deployment is a user-facing incident.

Why these environments exist

A change that works in isolation can still fail in production because production has different infrastructure, real data volumes, tighter IAM permissions, and real concurrent users. Each environment is a quality gate that filters out a different class of problem before the next stage.

When a problem is caught in dev, the cost is a code change. When it is caught in staging, the cost is a failed deployment and a fix. When it reaches production, the cost is user impact, potential data problems, and an incident response. Environments exist to move that cost as early in the process as possible.

Analogy

Think of it like a restaurant testing a new dish. The chef tries it first in the kitchen (dev). Then the staff taste it before service (staging). Only after that does it go on the menu for paying customers (production). You would not serve untested food to a guest, and you would not skip the staff tasting because you were in a hurry.

How it works in a real CI/CD pipeline

In a well-structured pipeline, code flows forward through environments rather than being rebuilt separately for each one.

  1. A developer pushes code. Cloud Build runs automated tests and builds a container image.
  2. The image is pushed to Artifact Registry and automatically deployed to dev.
  3. On merge to the main branch, the same image is promoted to staging. Cloud Deploy manages this promotion and tracks exactly which image version is running in each environment.
  4. After staging validation, a human approves the release. Cloud Deploy promotes the exact same image to production.

The critical detail is that the same container image (same digest, same SHA) moves from staging to production. Nothing is rebuilt. This means the artefact users receive in production is identical to the one validated in staging. Rebuilding a new image for production breaks that test-what-you-ship guarantee.

Development environment

Dev exists to give developers a fast feedback loop. It should be cheap, quick to deploy to, and tolerant of instability. A broken dev environment is an inconvenience, not an incident.

Dev is a safe place to experiment

Breaking dev costs nothing except a few minutes to fix. That is the point. If developers are afraid to push to dev, the environment is not doing its job. Keep it cheap, keep it permissive, and let people move fast.

Typical dev configuration in GCP

  • GCP project: my-app-dev, completely separate from staging and production
  • Cloud Run min-instances: 0, scaled to zero between active sessions to save cost
  • Cloud Run max-instances: capped low (3 to 5) to prevent cost overruns if something loops
  • Database: Cloud SQL on a small tier (db-f1-micro or db-g1-small), populated with synthetic or anonymised test data only
  • Deploy trigger: automatic on push to a feature branch, or on merge to main
  • IAM: developers have broad access (roles/editor or similar) to investigate issues quickly
  • Secrets: dev-specific values in Secret Manager under the dev project, never shared with other environments
  • Approvals: none
  • Monitoring: optional; no on-call expectations

What dev is good at catching

Dev catches obvious integration errors: does the application start, does it connect to its dependencies, do the core API paths respond correctly. It is not a meaningful proxy for production behaviour. A performance issue that appears under production load will not show up against a micro-tier database with scale-to-zero enabled.

Staging environment

Staging is the most important environment after production. Its value depends entirely on how closely it resembles production. A staging environment that is too small, too loosely configured, or too different in architecture does not catch the problems it is meant to catch. It just adds a step and provides false confidence.

For how to manage environment-specific values without duplicating your pipeline definition, see managing environments in CI/CD.

Typical staging configuration in GCP

  • GCP project: my-app-staging, isolated from both dev and production
  • Cloud Run min-instances: same as production, or at minimum 1. Not zero.
  • Cloud Run max-instances: same as production or a defined fraction
  • Cloud Run concurrency: identical to production
  • Database: same Cloud SQL tier as production (or one step below), same schema, anonymised production snapshot as data
  • Deploy trigger: automatic on merge to main via CI/CD pipeline or Cloud Deploy
  • IAM: developers have read access; all changes go through the pipeline
  • Secrets: staging-specific values in Secret Manager; see secrets in CI/CD pipelines for per-environment setup
  • Approvals: automatic deployment from main; human review required before promoting to production
  • Monitoring: full monitoring active; no on-call pager, but alerts should be reviewed

What staging is good at catching

Staging catches problems that only appear with production-like infrastructure: database connection pool exhaustion under realistic query patterns, IAM permission errors invisible in dev (where developers have broad access), Cloud Run cold start times with real image sizes, and memory pressure that only surfaces at production concurrency levels.

Staging parity matters

A staging environment that uses scale-to-zero Cloud Run and a micro-tier database will not catch performance or cold start issues. Staging must resemble production in architecture, not just in code version. The more staging diverges from production, the less useful it becomes as a gate.

Production environment

Production serves real users. Every change is deliberate and traceable. This is the environment where mistakes have immediate consequences, so the configuration reflects that: tighter access, mandatory approvals, full observability, and rollback readiness built in from the start.

No manual changes in production

Every console change that bypasses the pipeline is invisible to Terraform, undocumented, and unrepeatable. If you make a manual change to a Cloud Run service in the console, the next Terraform apply will revert it. Restrict direct access via IAM and route all changes through the pipeline, including urgent ones.

Typical production configuration in GCP

  • GCP project: my-app-prod
  • Cloud Run min-instances: 2 or more, which keeps instances warm so users do not experience cold start latency
  • Cloud Run max-instances: sized for peak traffic with headroom
  • Database: full production Cloud SQL tier, automated backups, point-in-time recovery enabled
  • Deploy trigger: Cloud Deploy promotion from staging with manual approval
  • IAM: developers have read-only access; each service runs as a least-privilege service account; no direct console changes
  • Secrets: production values in Secret Manager, rotated on schedule
  • Approvals: required: a Cloud Deploy approval gate before any deployment proceeds
  • Monitoring: full Cloud Monitoring with alerting policies and on-call rotation active
  • SLOs: defined, tracked, and tied to alert escalation

What changes in production compared with lower environments

The key differences are not just about scale. Production has different governance rules:

  • No developer deploys directly from their laptop or local machine
  • Every deployment goes through the same pipeline path that ran through staging
  • Rollback must be fast, using Cloud Deploy rollback or traffic splitting
  • Manual console changes that bypass Terraform or the pipeline are not permitted, even for urgent fixes
# Deploying to Cloud Run with production configuration
gcloud run deploy api-service \
  --image=europe-west2-docker.pkg.dev/my-app-prod/api/api:v1.2.3 \
  --region=europe-west2 \
  --service-account=api-service@my-app-prod.iam.gserviceaccount.com \
  --set-env-vars=ENVIRONMENT=production \
  --update-secrets=DATABASE_URL=database-url:latest

Dev vs staging vs production: side-by-side

DevStagingProduction
PurposeFast iterationPre-release validationServe real users
GCP projectmy-app-devmy-app-stagingmy-app-prod
TrafficDevelopers onlyQA / team testingReal users
DataSyntheticAnonymised snapshotReal user data
IAM accessBroad (editor)Read-only for devsRead-only for devs
Deploy triggerBranch pushMerge to mainCloud Deploy promotion
ApprovalsNoneNone (auto)Required
Min instances0 (scale to zero)1+ (matches prod)2+
MonitoringOptionalActive, no pagerActive, on-call
StabilityUnstable by designStableMust be stable
Change controlNonePipeline onlyPipeline + approval

Dev vs staging vs production vs test

Some teams add a dedicated test or QA environment between dev and staging. The terminology gets used inconsistently, so it is worth being clear about what each one is for.

  • Dev: developer sandbox with frequent, unstable deployments; catches obvious errors
  • Test / QA: a more stable environment for automated integration tests or manual QA sign-off, separate from individual developer work
  • Staging: production-like environment for final validation before release; confirms the deployment process and infrastructure configuration will hold up in production
  • Production: live environment serving real users

Staging is not the same as QA. QA is for finding bugs. Staging is for confirming that the deployment process and infrastructure configuration will work correctly under production conditions. Many teams combine QA and staging into one environment, which is fine as long as staging still closely mirrors production.

Note

Whatever you call your environments internally, what matters is that at least one environment closely mirrors production before changes reach users. The name is less important than the parity.

When to use this setup

Three separate environments is the right default for any application with real users. The specifics change depending on your situation.

  • Solo developer or small startup: all three environments still make sense. The overhead is low. Separate GCP projects cost nothing beyond the resources you deploy. Even a two-person team benefits from staging once the product has real users.
  • Regulated or high-risk workloads: three environments is a minimum. Regulated industries often require a full audit trail of every deployment, mandatory approval workflows, and data separation enforced by project boundaries rather than just by convention.
  • Internal tools: you might temporarily use only dev and production while the tool is in early development. That is a conscious trade-off, not a permanent approach. Internal tools can still cause serious damage if production is the only gate.
  • Customer-facing systems: all three environments with proper staging parity are non-negotiable once you have paying customers or SLAs.

If you are planning your Terraform directory structure to support multiple environments, Terraform project structure covers how to organise environment directories. For keeping Terraform state isolated per environment, see Terraform state management.

Common mistakes

  1. Staging does not match production. Scale-to-zero Cloud Run with a micro-tier database will not catch performance regressions, cold start problems, or connection pool exhaustion. If staging diverges from production in infrastructure, it stops being a useful gate.

  2. Using real user data in dev or staging. Real data creates privacy and compliance risks. Dev should use synthetic data. Staging should use an anonymised production snapshot. This is not optional if you handle personal data.

  3. Making direct console changes to production. Every manual console change is undocumented, invisible to Terraform, and unrepeatable. Restrict direct access via IAM. If a change cannot wait for the pipeline, that is a process problem, not a reason to bypass the pipeline.

  4. Treating staging as optional for small changes. Small changes can break production as easily as large ones, sometimes more so because they receive less scrutiny. Every change takes the same path through the pipeline.

  5. Rebuilding a different image per environment. If you rebuild from source for production, you are not deploying what you tested. Promote the same image digest from staging to production.

  6. Using one GCP project for all environments. Without separate projects, IAM isolation is much harder, billing is mixed, and a Terraform mistake in staging can affect production resources. Separate projects are the correct default.

  7. Sharing secrets across environments. Each environment should have its own secrets in its own Secret Manager instance. Sharing secrets means a staging compromise can expose production credentials.

Best practices for GCP environment separation

  • Use a separate GCP project for each environment, giving each its own IAM boundary and billing visibility
  • Give each service its own service account per environment, with the minimum IAM roles it actually needs
  • Store all secrets in Secret Manager with one instance per project and nothing shared between environments
  • Keep separate Terraform state per environment so a terraform destroy in staging cannot touch production resources
  • Promote the same container image through the pipeline rather than rebuilding at each stage
  • Configure full observability in staging, not just production. You cannot tune what you cannot see.
  • Plan rollback before you need it. Cloud Deploy supports rollback to a previous release, and canary deployments in production can limit blast radius further.
  • Use anonymised data snapshots for staging: realistic enough to surface issues, safe enough to give QA access
  • Document which environment each Cloud Build trigger targets so new team members understand the pipeline without having to reverse-engineer it

Frequently asked questions

Do I need a staging environment if I already have dev?

Yes. Dev is optimised for speed and is deliberately not production-like. Staging exists to catch problems that only appear with production-like infrastructure: the right database tier, correctly scoped IAM service accounts, and production-level concurrency settings. Dev catches obvious integration errors. Staging catches the subtler ones before they reach users.

Should staging and production be separate GCP projects?

Yes. Separate GCP projects provide IAM isolation (staging credentials cannot access production data), separate billing visibility, and separate Terraform state. A terraform destroy in staging cannot affect production resources if they are in a different project. Using one project for both is a shortcut that causes problems as the team grows.

Should staging use real user data?

No. Staging should use an anonymised snapshot of production data, not real user data. Real data in non-production environments creates privacy and compliance risks. Anonymised data is realistic enough to surface query performance issues and schema problems without exposing personal information.

Can a small team skip staging?

A very small team shipping an early-stage internal tool might temporarily use only dev and production. That is a conscious trade-off, not best practice. As soon as the product has real users or handles sensitive data, staging becomes worthwhile. The cost of running a staging environment is low compared with the cost of a production incident.

Should I deploy the same image from staging to production?

Yes. The exact same container image (same digest, same SHA) should be promoted from staging to production. Rebuilding a new image for production breaks the guarantee that what you tested is what users get. Cloud Deploy is built around this promotion model.

Last verified: 25 March 2026 Cloud services change frequently. Verify details against official documentation before making infrastructure decisions.