SfSkills Domains Docs GitHub

Home / devops / scratch-org-management

scratch-org-management

Use this skill when designing, configuring, or troubleshooting scratch orgs: definition file structure, edition selection, allocation limits, Org Shape, CI automation via ScratchOrgInfo, and lifecycle management from the Dev Hub. NOT for SFDX CLI basics (use apex/sf-cli-and-sfdx-essentials), sandbox management, or production org administration.

Open the skill folder on GitHub


Scratch Org Management

This skill activates when you need to design the shape of a scratch org (definition file), manage allocation limits across a team or CI system, troubleshoot provisioning failures, or automate scratch org lifecycle via the Dev Hub API. It assumes Dev Hub is already enabled; for basic CLI commands and first-time setup see sf-cli-and-sfdx-essentials.


Before Starting

Gather this context before working on anything in this domain:


Core Concepts

1. The Scratch Org Definition File

The definition file (config/project-scratch-def.json) is a JSON blueprint that tells Dev Hub exactly what kind of scratch org to provision. It is not part of sfdx-project.json; it is a standalone file in the config/ directory by convention.

Minimal required field:

{
  "edition": "Developer"
}

Full annotated example:

{
  "edition": "Enterprise",
  "description": "Feature branch — Communities + API",
  "duration": 7,
  "hasSampleData": false,
  "language": "en_US",
  "country": "US",
  "features": ["Communities", "LightningServiceConsole"],
  "settings": {
    "lightningExperienceSettings": {
      "enableS1DesktopEnabled": true
    },
    "mobileSettings": {
      "enableS1EncryptedStoragePref2": false
    }
  }
}

Key fields:

FieldRequiredNotes
editionYesControls base feature set — see Edition Types below
durationNoDays until expiry; default 7, max 30
featuresNoArray of feature strings; additive on top of edition
settingsNoMetadata API settings objects; most comprehensive config option
hasSampleDataNoDefault false; true pre-populates Accounts, Contacts, etc.
orgPreferencesNoDeprecated in favor of settings; still works but avoid for new orgs

2. Edition Types and What They Control

The edition field sets the base feature set and license model. Choose the edition that most closely matches the org your code will be deployed to in production or the target packaging environment.

EditionUse Case
DeveloperDefault for most feature development; lean, fast to provision
EnterpriseWhen production is Enterprise and you need Enterprise-only metadata
GroupTesting in small-business org shape
ProfessionalTesting Professional edition constraints (no Apex by default)
Partner DeveloperISV/partner package development in a Partner Business Org
Partner EnterpriseISV enterprise package testing

Do not use Developer edition if the production org is Enterprise and you need to test features that require Enterprise licensing — the org will provision successfully but will be missing feature flags.

3. Allocation Limits by Dev Hub Edition

Limits are enforced at the Dev Hub org level, not per user. All users sharing a Dev Hub share the same pool.

Dev Hub EditionDaily CreatesMax Active Orgs
Developer Edition63
Enterprise Edition4020
Performance Edition10050
Unlimited Edition10050
Partner Business OrgVaries; typically 200+ daily / 100 active for active PBOs

Source: Salesforce DX Developer Guide — Supported Scratch Org Editions and Allocations

Expiration: Default is 7 days. Max is 30 days. Expired orgs are automatically deleted by Salesforce along with their ActiveScratchOrg records. Specify --duration-days at creation time; you cannot extend a scratch org after it is created.

4. Dev Hub Objects for Automation

Two standard objects in the Dev Hub org expose scratch org state for SOQL queries and automation:

SELECT Id, OrgName, ExpirationDate, CreatedBy.Name
FROM ActiveScratchOrg
WHERE ExpirationDate <= NEXT_N_DAYS:2
ORDER BY ExpirationDate ASC

5. Org Shape

Org Shape captures the edition, features, settings, and licenses of a specific source org (typically production or a staging sandbox) and uses them as the blueprint for scratch org creation — without manually maintaining a definition file for every feature toggle. Org Shape is available for Enterprise and above Dev Hubs.

When to prefer Org Shape over a hand-maintained definition file:

When to keep a definition file:


Common Patterns

Mode 1: Create a Scratch Org from a Definition File

When to use: Standard feature branch development; new team member onboarding; CI jobs.

# Create org from definition file, set as default, expire in 14 days
sf org create scratch \
  --definition-file config/project-scratch-def.json \
  --alias feature-myfeature \
  --duration-days 14 \
  --set-default \
  --target-dev-hub MyDevHub

# Push source to the new org
sf project deploy start

# Open the org in a browser
sf org open --target-org feature-myfeature

# When done — explicitly delete to free allocation
sf org delete scratch --target-org feature-myfeature --no-prompt

Mode 2: Audit and Manage Active Org Pool from Dev Hub

When to use: Team lead or CI admin needs to reclaim allocations; pre-flight check before a CI run; regular hygiene.

# List all orgs known to the local CLI
sf org list --all

# From inside the Dev Hub org, query active orgs
sf data query \
  --query "SELECT OrgName, ExpirationDate, CreatedBy.Name FROM ActiveScratchOrg ORDER BY ExpirationDate ASC" \
  --target-org MyDevHub

# Delete a specific scratch org by alias
sf org delete scratch --target-org stale-org-alias --no-prompt

Mode 3: Automate in CI (GitHub Actions pattern)

When to use: Pull request pipelines that need a fresh org per run and must release it when done.

# .github/workflows/ci.yml (relevant steps)
- name: Authenticate Dev Hub
  run: sf org login jwt --client-id ${{ secrets.SF_CLIENT_ID }} \
       --jwt-key-file server.key \
       --username ${{ secrets.SF_USERNAME }} \
       --alias DevHub --set-default-dev-hub

- name: Create scratch org
  run: sf org create scratch \
       --definition-file config/project-scratch-def.json \
       --alias ci-org --duration-days 1 \
       --target-dev-hub DevHub

- name: Deploy and test
  run: |
    sf project deploy start --target-org ci-org
    sf apex run test --target-org ci-org --result-format tap --code-coverage

- name: Delete scratch org
  if: always()
  run: sf org delete scratch --target-org ci-org --no-prompt

The if: always() guard ensures the org is deleted even when prior steps fail, preventing allocation leaks.


Decision Guidance

SituationRecommended ApproachReason
Team hitting active org limit dailyEnforce --duration-days 1 for CI orgs; add if: always() delete step to pipelineActive limit is per Dev Hub, shared across all users
Scratch org missing a feature present in productionAdd feature string to features array, or switch to Org ShapeFeatures not declared at creation cannot be added after provisioning
Need to reproduce a production-specific bugUse Org Shape sourced from production replica or staging sandboxCaptures actual feature flags, avoiding manual enumeration errors
ISV building a managed packageUse Partner Developer or Partner Enterprise edition with linked namespacePartner editions include packaging permissions not in standard Developer edition
New developer hits "allocation exceeded"Run SOQL on ActiveScratchOrg in Dev Hub; delete orgs older than 7 daysExpired orgs pending auto-cleanup still count against the limit
CI org creation failing intermittentlyAdd retry logic; check ScratchOrgInfo.Status for Failed recordsScratch org provisioning is asynchronous; transient failures occur under heavy load

Step-by-step instructions for an AI agent or practitioner activating this skill:

  1. Gather context — confirm the org edition, relevant objects, and current configuration state
  2. Review official sources — check the references in this skill's well-architected.md before making changes
  3. Implement or advise — apply the patterns from Core Concepts and Common Patterns sections above
  4. Validate — run the skill's checker script and verify against the Review Checklist below
  5. Document — record any deviations from standard patterns and update the template if needed

Review Checklist

Run through these before marking work in this area complete:


Salesforce-Specific Gotchas

Non-obvious platform behaviors that cause real production problems:

  1. Daily limit is a rolling 24-hour window, not a midnight reset — The daily scratch org limit resets on Salesforce's rolling 24-hour window tied to the Dev Hub instance, not the user's local midnight. Teams scheduling CI jobs at midnight may still be within the previous window's count.
  2. orgPreferences is deprecated and silently drops settings — Definition files using the old orgPreferences format provision successfully, but some settings are silently ignored. The correct format is settings using Metadata API setting objects. A definition file that "worked before" may be missing settings on newer API versions without any error.
  3. Scratch org expiration cannot be extended after creation — The --duration-days flag is set once at creation time. There is no extension command. If work is in progress on an expiring org, the only recovery path is to push source, create a new org, and re-pull — or extract the org's metadata before expiry.
  4. Deleting from Active Scratch Orgs list does NOT delete the ScratchOrgInfo record — ScratchOrgInfo is a permanent audit record of every creation request. Only ActiveScratchOrg is deleted (and the org freed). This confuses practitioners expecting both records to be cleaned up, but it is correct behavior.
  5. hasSampleData: true dramatically slows provisioning — Sample data injection adds 3–5 minutes to scratch org creation. In CI with parallel jobs, this compounds significantly. Disable it unless tests depend on standard sample objects.

Output Artifacts

ArtifactDescription
config/project-scratch-def.jsonScratch org definition file — source of truth for org shape in the project
sf org list --all outputSnapshot of all locally tracked orgs for audit
SOQL on ActiveScratchOrgReal-time view of active pool from Dev Hub
CI pipeline YAML snippetWorkflow fragment for automated scratch org lifecycle

Package files