---
title: "Validation-only deploys and quick deploy"
url: "https://trailassembly.com/validation-only-and-quick-deploy/"
topic: "DevOps and Release"
published: "2026-09-21T11:46:16+00:00"
updated: "2026-09-23T11:03:40+00:00"
---

# Validation-only deploys and quick deploy

**Run a validation-only deployment against production ahead of your window, and if it passes with tests, you get a quick deploy that skips the test run entirely — turning a two-hour release into a few minutes.** The validation is good for four days. This is the single highest-value deployment habit available on the platform and a surprising number of teams do not use it.

## How it works

A validation-only deployment does everything a real one does (compiles, checks dependencies, runs the specified tests), and then discards the result instead of committing it. Salesforce keeps the validated deployment for four days. Within that window you can deploy it without re-running the tests.

```apex
# Validate, running local tests
sf project deploy validate \
  --source-dir force-app \
  --test-level RunLocalTests \
  --target-org production

# Note the job Id, then within four days:
sf project deploy quick --job-id 0AfXXXXXXXXXXXXXXX --target-org production
```

Setup → Deployment Status shows validated deployments with a Quick Deploy button, which is the same thing from the UI.

## The conditions for quick deploy to be available

- The validation must have run tests. A validation with `NoTestRun` cannot be quick-deployed.

- The test level must be adequate for production — `RunLocalTests` or `RunAllTestsInOrg`, or `RunSpecifiedTests` covering everything required.

- The validation must have succeeded completely.

- It must be within four days.

- The deployment contents must be unchanged. Any edit means a new validation.

That last point is the one that catches teams: a last-minute fix invalidates the validation, and the quick deploy button disappears. If you are still editing, you are not ready to validate.

## Choosing a test level

| Level | Runs | Use for |
| --- | --- | --- |
| NoTestRun | Nothing | Sandboxes only; blocks quick deploy |
| RunSpecifiedTests | Named classes | Targeted validation; each class must hit 75% |
| RunLocalTests | All tests except managed packages | The production default |
| RunAllTestsInOrg | Everything, packages included | Before a major upgrade |

`RunLocalTests` is the right default for production. `RunSpecifiedTests` is tempting for speed and has a trap: every class you name must independently reach 75% coverage, and any class not named gets no coverage credit, so a partial list can fail on coverage grounds even when all the tests pass.

## The workflow this enables

The point is not speed for its own sake. It is moving the risky, slow, failure-prone part of a release out of the change window.

1. **Two days before the window:** validate against production with `RunLocalTests`. It takes as long as it takes, and nobody is waiting.

2. **Fix whatever it finds.** This is where you discover the production-only dependency, the test that assumes sandbox data, the field a report depends on.

3. **Re-validate** until clean.

4. **In the window:** quick deploy. Minutes, with no test run and no discovery.

The failures that used to happen at 11pm now happen on a Tuesday afternoon. That is the entire value proposition, and it is worth more than the time saved.

## What validation does not catch

Being clear about this matters, because a green validation creates confidence that should be bounded.

- **Data-dependent failures.** Validation does not run against your production data. A validation rule that rejects existing records still will.

- **Post-deploy steps.** Manual configuration, feature activation, permission set assignment. None of it is validated.

- **Behaviour.** Tests passing means tests passed. It does not mean the feature does what the business asked for.

- **Destructive changes against real data.** Deleting a field validates fine and still deletes the data on deploy.

- **Performance at production volume.** A trigger that works on 200 sandbox records may not on a production batch.

## Practical notes

**Capture the job Id.** Quick deploy needs it. Have CI print it and store it with the release ticket, because hunting through Deployment Status during a window is exactly the friction you were removing.

**Validate what you will deploy.** Validating a directory and then deploying a manifest is validating something else. Use identical parameters for both commands.

**Mind the four days.** A validation on Thursday for a Tuesday release has expired. Plan the validation into the release calendar rather than leaving it to whoever remembers.

**It still consumes the org’s deployment concurrency.** Do not validate during another team’s deployment window.

## Frequently asked

### Can I quick deploy a change set?

Yes. A validated inbound change set shows a Quick Deploy option under the same conditions. It is not a CLI-only feature.

### Does a quick deploy skip tests entirely?

Yes, which is the whole point. The tests already ran during validation and the contents have not changed since.

### What if a test starts failing between validation and deploy?

The quick deploy does not re-run tests, so it will not notice. This is a real gap: a validated deployment reflects the org as it was at validation time. If anything significant changed in the org meanwhile, re-validate.

### How long is the validation really valid?

Four days. After that the entry expires and you validate again.

### Should CI validate on every pull request?

Validating against a sandbox on every PR is good practice. Validating against production on every PR is not. It consumes deployment capacity and production is not where you find out a branch does not compile.

---

*Reference: Deploy and Validate Metadata*, *Salesforce CLI Command Reference* and *Metadata API Developer Guide*, Salesforce.

---

Source: https://trailassembly.com/validation-only-and-quick-deploy/
Trail Assembly — independent Salesforce write-ups.
