In 2026 there are three deployment paths from sandbox to production. The interview answer needs to name all three, recommend the modern one, and explain when the legacy options are still right. Naming only Change Sets in 2026 dates the candidate badly.
The 60-second answer
Modern path: source-tracked sandbox → Git → CI pipeline (GitHub Actions / GitLab / Copado / Gearset) running sf project deploy start --target-org production --test-level RunLocalTests. Production deployments require 75% Apex test coverage across the org, no triggers below 1%, all tests passing. Before deploying, validate with --dry-run against production. Pre-2024 alternative is Change Sets between connected orgs — still in use for admin-heavy orgs with no Git workflow. For metadata not in source format, the Metadata API (sf project deploy start -d manifest/) is the universal fallback.
The three paths
| Path | When it’s right | Limits |
|---|---|---|
| Salesforce CLI + Git + CI (recommended) | Any org with developers, multi-environment promotion, version control | Requires sfdx-project.json, Git workflow discipline |
| Change Sets (legacy) | Admin-only orgs, urgent one-off fixes between two connected sandboxes/prod | No version control, no rollback, deploys must be done by a person clicking |
| Metadata API direct | Headless deploys, packaged distributions, large one-off metadata moves | Needs package.xml; lower-level than DX |
For a developer interview, lead with the CLI/Git path. Mention Change Sets as the alternative for admin-heavy work.
Modern path — Salesforce DX + CI
Step 1 — Source-tracked sandbox + Git
Every Apex class, LWC, flow, and custom object lives in version-controlled source under force-app/main/default/. The sandbox is source-tracked (Developer or Developer Pro), so the CLI knows what changed without you remembering.
# Pull what changed in the sandbox into source format
sf project retrieve start --target-org my-sandbox
# Stage and commit
git add force-app/
git commit -m "feat: add scenario-based opportunity validation"
git push origin feature/scenario-validation
Step 2 — Pull request and CI validation
A PR triggers CI, which runs a validation-only deploy against production (no commit):
sf project deploy start \
--target-org production \
--dry-run \
--test-level RunLocalTests \
--wait 60
Validation does everything a real deploy does except commit. If coverage drops below 75% or any test fails, the build is red and the PR can’t merge.
Step 3 — Actual deploy on merge
After merge, the same command without --dry-run:
sf project deploy start \
--target-org production \
--test-level RunLocalTests \
--wait 120
RunLocalTests runs every Apex test in the org except those from managed packages. For a small change you can scope:
sf project deploy start \
--target-org production \
--test-level RunSpecifiedTests \
--tests OpportunityValidationTest \
--tests OpportunityValidationTest2 \
--wait 120
The narrower test scope is faster but requires you to know which tests exercise the changed code. Most pipelines default to RunLocalTests for safety.
Step 4 — Quick deploys
If you validated within the last 4 days and want to ship the validated package without re-running tests:
sf project deploy quick --job-id 0Af3z00000abcXYZ --target-org production
This is the Friday-afternoon hotfix path — validate Monday, ship later in the week without burning another 30-minute test run.
Production deployment requirements
| Rule | Detail |
|---|---|
| Test coverage | 75% of all Apex code in the org, post-deploy |
| Per-trigger coverage | At least 1% on every trigger (the trigger must be touched by a test) |
| All tests must pass | A single failure blocks the entire deploy |
| Validation expires in 4 days | Quick Deploy must happen within 4 days of validation |
| Change Set deploys | Lock the receiving org during deploy; concurrent admin changes are blocked |
The 75% number is org-wide post-deploy — not per-class. You can have a 0%-coverage class as long as the rest of the org is high enough to clear 75%. (Don’t actually do this — it’s just clarifying the math.)
Legacy path — Change Sets
Still common in admin-heavy orgs. The flow:
- Source org (Sandbox) → Outbound Change Sets → Add components.
- Upload to target org (Production) → appears in Inbound Change Sets.
- Validate Inbound Change Set → click Deploy.
Pros: no CLI, no Git, no engineer. Cons: no version control, no rollback, no PR review, no CI testing, easy to miss a dependency, every deploy is a manual click.
In 2026, Change Sets are mostly used for admin-only metadata (flows, page layouts, permissions) when there’s no DevOps practice. Mention you’d migrate them to DX if you joined the team.
Pre-deploy checklist
Before pushing the deploy button:
- Validate first (
--dry-run). Surface coverage gaps and test failures without consuming a deploy slot. - Backup production metadata —
sf project retrieve start --target-org production --manifest package.xmllets you re-deploy the previous state if you need to roll back. - Run tests in the sandbox matching production scope, including managed-package tests if relevant.
- Check for destructive changes — deleting a custom field or object requires
destructiveChanges.xml. Treat carefully; deleted fields can take data with them. - Schedule a deployment window if it’s a major release; users get errors during the deploy.
- Have a rollback plan — either the previous-state metadata package or a documented manual undo for each change.
Anti-patterns
- Deploying with
NoTestRun— production won’t allow it for code. Even where allowed, you’ve removed your safety net. - Pushing directly from a developer’s laptop without PR review or CI — bypasses every quality gate.
- Skipping validation —
--dry-runexists for a reason. Use it. - Destructive changes in the same package as the new code — split into two deploys; if the new code fails, you haven’t already deleted the old field.
- Forgetting the org-wide 75% threshold — adding one untested 500-line class can drop the whole org below 75% and block the deploy.
- Deploying flows from inactive state and re-activating manually — automate flow activation in your CI; manual activation is the #1 cause of “I deployed and nothing changed” tickets.
How to answer in 30 seconds
“DX path: source-track the sandbox, commit to Git, CI validates with sf project deploy start --dry-run --test-level RunLocalTests, then deploys the same way on merge. Production requires 75% org-wide Apex coverage, all tests passing, every trigger touched. Change Sets are the legacy admin-friendly fallback. Quick Deploy lets you ship a previously validated package without re-running tests.”
How to answer in 2 minutes
Walk the three paths (DX, Change Sets, Metadata API direct). Then walk the DX flow: source-tracked sandbox → Git → PR → CI validation with --dry-run and --test-level RunLocalTests → merge → deploy. Mention the production-specific rules (75% coverage, every trigger ≥1%, all tests pass, validations expire in 4 days). End with the pre-deploy checklist — validate, backup, schedule, plan rollback.
Likely follow-up questions
- What’s the difference between RunLocalTests and RunAllTestsInOrg?
- How do you handle destructive changes in a deployment?
- What’s the difference between a Developer and Developer Pro sandbox?
- How do you deploy a profile without overwriting target-org permissions?
- What’s the Quick Deploy and when do you use it?
Verified against: Salesforce CLI Reference — sf project deploy, Deploying Apex to Production, Change Sets Overview. Last reviewed 2026-05-19.