warm_max grows a pool on demand, but nothing shrinks it back once the target decays: trimWarm runs only from SetPools (sandboxd/pool/setpools.go) and drain; refillOnce (sandboxd/pool/refill.go) fills while warm < target and never trims while warm > target.
Observed on the testbed with warm: 2, warm_max: 8 (both #179 and #180 binaries): a burst of ~14 claims/s for six seconds raised the target to 4 and the pool to 4 warm VMs; a minute of silence brought the target back to 2, and three minutes later the pool still held 4. Every warm VM above the floor holds its memory (about 512 MiB for small) until the next PUT /v1/pools or a restart, so after any busy period a pool sits at that period's high-water mark and warm_max only ever ratchets up.
docs/deploy.md says the target "decays back over ~a minute of silence"; readers take that to mean the pool does too.
Options, both a few lines in refillOnce:
- Trim to the target once it has been below
len(p.warm) for one decay period (rateDecayTau, 60 s), so a pool does not churn on a fluctuating load.
- Trim on every refill tick with a hysteresis band (for example keep up to
target + 1).
Either way the trimmed VMs go through the same destroy path SetPools uses today. Not a hot-path change; needs one unit test with the fake engine and a testbed check that the pool actually shrinks after silence.
warm_maxgrows a pool on demand, but nothing shrinks it back once the target decays:trimWarmruns only fromSetPools(sandboxd/pool/setpools.go) and drain;refillOnce(sandboxd/pool/refill.go) fills whilewarm < targetand never trims whilewarm > target.Observed on the testbed with
warm: 2, warm_max: 8(both #179 and #180 binaries): a burst of ~14 claims/s for six seconds raised the target to 4 and the pool to 4 warm VMs; a minute of silence brought the target back to 2, and three minutes later the pool still held 4. Every warm VM above the floor holds its memory (about 512 MiB forsmall) until the nextPUT /v1/poolsor a restart, so after any busy period a pool sits at that period's high-water mark andwarm_maxonly ever ratchets up.docs/deploy.mdsays the target "decays back over ~a minute of silence"; readers take that to mean the pool does too.Options, both a few lines in
refillOnce:len(p.warm)for one decay period (rateDecayTau, 60 s), so a pool does not churn on a fluctuating load.target + 1).Either way the trimmed VMs go through the same
destroypathSetPoolsuses today. Not a hot-path change; needs one unit test with the fake engine and a testbed check that the pool actually shrinks after silence.