How to maintain the scratch org pool
Pools only stay useful if they are kept full and free of stale orgs. This guide covers the operator tasks. For how pooling works, see scratch org pooling.
One-time: make the DevHub pooling-ready
Pooling stores its state in custom fields on the DevHub's ScratchOrgInfo. Deploy the pooling
metadata once per DevHub:
This installs the ScratchOrgInfo fields, the allocation-race validation rule, and the pooling
permission sets. Until it runs, every pool command errors — the fields it queries do not exist.
Define a pool
Create config/project-<tag>-pool-def.json. Every key, its type and default is in the
pool definition file reference; a working minimum:
{
"tag": "ci",
"maxAllocation": 10,
"maxOrgsPerRun": 4,
"durationDays": 1,
"seedScript": "config/scratch-org-setup/ci-pool-seed.mjs",
"seedBaseline": "branch:master"
}
- Scale a pool out with more parallel pipeline steps, keeping
steps × maxOrgsPerRun ≤ maxAllocation. - Leave
seedConcurrencyat its default of4— it is a property of the runner, not of the pool size (why). - Set
seedBaselinewhen pull requests should delta-validate against pooled orgs; without it, orgs validate by full push. seedScriptis your own module — see write a pool seed script.
Top a pool up
It creates up to maxOrgsPerRun orgs (the exact formula is in the
pool definition file reference), seeds each, stamps its
baseline commit, and marks it available. On CI this is the scheduled per-tag Maintain … Pool
pipeline (custom pipelines).
Inspect and release
npm run org:pool:list -- --devhubusername devhub # totals per tag
node scripts/dia-scripts/index.mjs org pool-fetch --devhubusername devhub --tag ci # claim one
node scripts/dia-scripts/index.mjs org pool-release --devhubusername devhub --username <org> # return one
Clean up
Deletes the pool's orgs wholesale (hub-side, by deleting the ScratchOrgInfo records). Add
--allocated-only to remove just the claimed ones, or --id <recordId> for a single org.
Cleanup is an operator tool, not a schedule
cleanup removes every org for a tag. It is for resetting a pool, not routine maintenance —
routine top-up is prepare on a schedule.