Start free
Andrew Hanna

Andrew Hanna

Pre-Warmed Scratch Org Pooling: The Hidden Cap on ISV Release Velocity

Pre-Warmed Scratch Org Pooling: The Hidden Cap on ISV Release Velocity

Short answer: a pre-warmed scratch org pool is a set of scratch orgs created and fully provisioned in advance, so a build or a developer claims a ready environment instead of waiting for one. For ISV teams it matters more than for org-to-org teams, because every package validation pays the full cost of creating an org and installing a dependency chain before a single test runs. Pooling moves that cost off the critical path.

Nobody puts "scratch org creation time" on a roadmap slide. It still sets the ceiling on how often an ISV can validate a package, and most teams never see it because the wait is spread across every pull request instead of showing up as one line item.

What is pre-warmed scratch org pooling?

A pool is a background job that keeps N scratch orgs alive and ready, each already carrying whatever your build needs: the right edition and features, dependency packages installed, seed data loaded, permission sets assigned. When a pipeline or a developer asks for an environment, the pool hands one over and quietly starts a replacement.

The definition is boring. The consequence is not: the time to a usable org drops to the time it takes to check one out, and it stops varying with how complex your package tree got last quarter.

Why does scratch org creation time cap ISV release velocity?

Walk through what a single package validation actually does:

  1. Create the scratch org and wait for Salesforce to provision it.
  2. Install the dependency chain, one managed package at a time, in order.
  3. Install or deploy the package under test.
  4. Load seed data, assign permission sets, run any setup Apex.
  5. Run the tests. This is the only step that produces information.

Steps 1 to 4 are queue time. They return the same result every run, and for an ISV with a real dependency graph they usually dominate the total. That is the quiet cap: as the package tree grows, feedback gets slower even though the test suite has not changed, so teams respond by validating less often, batching more changes per validation, and finding conflicts later. Nobody decides to slow down. It just happens.

The cost lands hardest exactly where ISVs feel it: pull request checks, nightly regression across editions, and the pre-release run against every version you still support in subscriber orgs.

What does a warm pool actually change?

  • Feedback time stops tracking dependency depth. Adding a fifth dependency no longer adds minutes to every PR.
  • Parallelism becomes affordable. Testing three editions at once is a checkout of three orgs, not three cold builds.
  • Failures get honest. When provisioning is off the critical path, a red build is far more likely to be your code than a flaky install step.
  • Reviewers get an org, not a diff. Handing a reviewer a live environment stops being a favour and becomes the default.

How many orgs can an ISV actually pool?

This is where the plan meets the allocation. Salesforce documents the limits for partners: an active Partner Business Org gets 150 active scratch orgs and 300 per day, and a trial PBO gets 20 active and 40 per day (see the Salesforce partner allocation docs). Two things follow.

First, the daily allowance is roughly double the active one, which is Salesforce telling you that churn is expected and hoarding is not. Second, a pool is not free: every org sitting warm is an active org you cannot use elsewhere. Size the pool to your peak concurrent demand plus a small buffer, not to your headcount.

Is a scratch org snapshot the same as a pool?

No, and the difference is worth precision because they solve adjacent problems. A snapshot is a point-in-time copy of a scratch org including installed packages, features, licenses, metadata and data, and you create new orgs from it. That removes the setup work. It does not remove the wait for provisioning.

Snapshots also come with their own constraints: they expire after 90 days, allocations run from 3 on Developer Edition up to 100 on Unlimited and Performance, and connected apps, external credentials and named credentials are not copied. For ISVs that means a snapshot goes stale every time a dependency version moves.

The two compose well. Build the pool from a snapshot and you skip both the setup work and the wait.

How do you run a pool without burning your allocation?

  1. Separate the pools by purpose. A short-lived CI pool and a longer-lived developer pool have different expiry and different contents.
  2. Pin dependency versions in the pool definition. A pool built on "latest" is a pool that silently drifts away from what you ship.
  3. Replenish continuously, not once a night. Top up as orgs are claimed so the pool never empties mid-morning.
  4. Expire aggressively. Old warm orgs are stale orgs holding active allocation hostage.
  5. Monitor depth, not just success. The number that predicts a bad week is how often the pool hit zero.

Where can you get pooling?

You can build it yourself with the open source sfp tooling the flxbl project documents, which is how most early adopters got here. In Serpent, scratch orgs are available on every plan and pre-warmed pooling ships on Scale and Enterprise, alongside the 1GP and 2GP workflows, cross-package dependency resolution and AppExchange release gates package teams need on the same platform. Whichever route you take, insist that the pool understands your dependency graph. A pool of empty orgs solves the smaller half of the problem.

If your PR checks have quietly crept from four minutes to twenty, look at what those twenty minutes buy before you optimise a single test. Serpent is built for exactly that team.

FAQ

How big should a scratch org pool be?

Start at your peak concurrent demand plus two. Track how often the pool hits zero and add capacity only when it does, because every warm org consumes your active scratch org allocation.

Do pooled scratch orgs count against Salesforce limits?

Yes. A scratch org is active from creation until it expires or is deleted, so a warm pool consumes active allocation the whole time it sits idle.

Should we use snapshots or pooling?

Both, if you can. Snapshots cut the setup work inside an org; pooling cuts the wait for the org itself. Building your pool from a snapshot gives you both.

Does pooling help org-to-org teams too?

Less. Without a dependency chain to install, cold creation is much cheaper, so the payback is smaller than it is for package teams.

Related Articles

Curious about faster shipping before you dive in? Let's talk

Commitment free!