Scratch Orgs: The Salesforce Development Workflow Nobody Explains Properly
Most Salesforce developers hear "scratch org" for the first time and mentally file it under "another kind of sandbox." That mistake causes almost every early problem people have with them. A scratch org is not a smaller sandbox. It is a completely different model of how a Salesforce environment gets built, used, and thrown away — and once that model clicks, the rest of the modern Salesforce development workflow (source tracking, CI/CD, package-based development) makes a lot more sense.
What a scratch org actually is
A sandbox is a copy of an existing org. It inherits whatever metadata, and optionally whatever data, already lives in the org it was copied from. A scratch org has no parent org to copy. It is built from nothing, using two inputs only: a definition file that describes the org's shape (edition, features, settings) and whatever source is sitting in your local project or repository at the moment you create it.
That second part is the important one. A scratch org contains exactly what you deploy into it — nothing more. There is no accumulated five-year history of fields nobody remembers adding. If it's not in your source, it does not exist in the org. This is what people mean when they call scratch orgs "source-driven."
Creating one
Before you can create a scratch org you need a Dev Hub — a Salesforce org with the Dev Hub feature enabled, authorized once via the CLI. Every scratch org you create afterward is provisioned against that Dev Hub and counts toward its daily and concurrent scratch org limits.
The creation command itself is a single line:
sf org create scratch -f config/project-scratch-def.json -a scratch-dev --set-default --duration-days 7
-f points at the definition file, -a assigns an alias so you can refer to this org by name instead of a username, --set-default makes it the org every subsequent CLI command targets unless you specify otherwise, and --duration-days sets how long it lives before Salesforce deletes it automatically.
The scratch org definition file
config/project-scratch-def.json is where you describe the shape of the org you want — edition, enabled features, org preferences, language, currency. A minimal example:
{
"orgName": "Real Syllabus Dev",
"edition": "Developer",
"features": ["EnableSetPasswordInApi"],
"settings": {
"lightningExperienceSettings": {
"enableS1DesktopEnabled": true
},
"mobileSettings": {
"enableS1EncryptedStoragePref2": false
}
}
}
This file lives in version control alongside your metadata. That means every developer on the team — and every CI job — creates an org with an identical shape. No more "it works in my sandbox" because everyone's sandbox drifted independently over time.
Source tracking: the part that changes how you work
Sandboxes require you to manually track what changed and manually deploy it — change sets, metadata API retrieves, or discipline with a source control diff. Scratch orgs track source automatically. The CLI knows what you've already pushed and what's changed locally since, so pushing and pulling only moves the delta.
sf project deploy start // push local source changes into the scratch org
sf project retrieve start // pull changes made in the org back into local source
In practice this means you build a feature, push it to see it running, make a change directly in the org UI if that's faster for something like a Flow, pull that change back into source, and repeat. The scratch org and your local repository stay in sync without you manually reconciling anything.
Lifespan and expiry — the part people forget
A scratch org is temporary by design. The default duration is 7 days; the maximum is 30. Once it expires, Salesforce deletes it — permanently, including any data or configuration that only ever existed in the org and not in your source.
This is not a limitation to work around. It's the entire point of the model. If losing a scratch org would lose real work, that work should not have lived only in the org. Anything that matters belongs in source control, ready to be pushed into a brand-new scratch org in seconds.
Managing orgs you've created
Because scratch orgs are disposable and you'll create many of them, you need to see what you have and clean up what you don't:
sf org list // shows all authorized orgs, including active scratch orgs and days remaining
sf org delete scratch -o scratch-dev --no-prompt // deletes immediately instead of waiting for expiry
sf org list is the command you'll run most — it tells you which scratch orgs are still alive, which are about to expire, and which alias points at which username. Deleting explicitly (rather than waiting for expiry) is good practice once you're done with a feature, since Dev Hubs have limits on concurrent active scratch orgs.
Aliases: don't fight usernames
Every org the CLI creates gets an auto-generated username you will never remember. The -a flag at creation time assigns a human-readable alias instead — scratch-dev, pr-482, feature-loyalty-flow — and every CLI command afterward can target the org by that alias. Teams that adopt a naming convention (alias per feature branch or per ticket number) make it trivial to know which org belongs to which piece of work, especially when several are alive at once.
Where scratch orgs actually shine: CI/CD
The disposable, source-driven nature of scratch orgs is exactly what automated pipelines need. A typical CI setup: every pull request triggers a pipeline that authenticates to the Dev Hub, creates a fresh scratch org, pushes the branch's source into it, runs Apex tests, and then deletes the org — win or lose. No environment drifts, because nothing persists between runs. No queue for a shared sandbox, because every PR gets its own disposable org.
This is the workflow that makes "it passed CI" actually mean something: the tests ran against a clean org built from exactly the code being reviewed, not a sandbox that's accumulated eighteen months of unrelated changes.
Common mistakes when switching from sandboxes
The most common error is treating a scratch org like a sandbox you forgot to seed with data — spending an hour manually clicking through Setup to configure permission sets, page layouts, and record types that should have been in source from the start. If you find yourself repeating manual setup steps every time you create a fresh scratch org, that configuration belongs in your metadata, not in your memory.
The second common mistake is assuming a permission set gets automatically assigned to the default user on org creation. It doesn't — you assign it explicitly, usually via a post-creation script or a documented manual step, so new team members and CI pipelines both know it needs to happen.
Scratch org pools: the next step
Teams running high-frequency CI find that even fast scratch org creation adds up across dozens of daily pipeline runs. Scratch org pools — pre-created, pre-configured orgs sitting ready to be claimed — remove that creation time from the critical path entirely. It's an optimization worth knowing about once your team's pipeline runs often enough that creation time becomes the bottleneck, but it's not something you need on day one.
Scratch orgs reward the same instinct that makes source control valuable everywhere else: nothing important should live only in one place that can disappear. Once your metadata, configuration, and permission assignments are genuinely captured in source, a scratch org stops being a fragile, temporary thing to be careful with — it becomes disposable in the best sense, something you create, use, and destroy without a second thought.
Frequently Asked Questions
What is a scratch org in Salesforce?
A scratch org is a temporary, fully-configured Salesforce environment created on demand from a definition file and your version-controlled source. Unlike a sandbox, it isn't copied from production — it's built fresh from whatever metadata is in your repository, which makes it predictable, disposable, and ideal for feature development and CI pipelines.
How long does a scratch org last before it expires?
Scratch orgs expire automatically — the default duration is 7 days, and the maximum you can request is 30 days. Once an org expires it is gone permanently, including any data in it, which is why source-driven development (never storing important work only in the org) is the whole point of the model.
Do I need a Dev Hub to create scratch orgs?
Yes. Scratch orgs can only be created from an org with the Dev Hub feature enabled. You authorize the Dev Hub once with the Salesforce CLI, and every scratch org you create afterward is provisioned against it and counts against your org's daily and active scratch org limits.
Why do teams use scratch orgs instead of sandboxes for development?
Scratch orgs are cheap to create and destroy, come up clean in seconds to minutes rather than hours, and force source tracking discipline because nothing exists in the org unless it was pushed from your repository. This makes them a natural fit for one-org-per-feature-branch workflows and CI/CD pipelines where a fresh, disposable environment is spun up and torn down for every pull request.