Warm starts
Starting an interpreter inside a sandbox costs time before the first line of your code runs. Workers pay that cost ahead of time, off the critical path, so the job you start finds a runner already waiting. Nothing to turn on and no paid tier: every script on every plan gets it.
- Know what a warm runner is and why each one still serves only one job
- Tell which JavaScript and TypeScript scripts take the fast path
- Understand what a flow reserves before a loop starts
- Tune or turn off the warm pool on a self-hosted worker
A runner already waiting
Each worker keeps a few warm runners for Python and for TypeScript/JavaScript: processes that have already booted the interpreter inside their sandbox and are waiting for a job. When a job is claimed, it is handed one of them, and a replacement starts booting in the background.
What is kept warm
| Language | How it starts fast |
|---|---|
| Python | A pre-booted runner from the warm pool. |
| TypeScript, JavaScript | A fast path that runs the script in an in-process engine when it can, else a pre-booted runner. |
| C, C++ | The compiled binary is cached by its code, so only the first run compiles. |
| PostgreSQL, MySQL | Connections to each database are kept open (up to 4 per connection per worker). |
The JavaScript and TypeScript fast path
A script takes the fast path when it bundles cleanly and does not import the waiso SDK. Anything else — a compile error, a thrown error, a timer or file access that needs a full runtime — falls back to the regular runner, whose answer is the one that counts. The fast path serves the latest runtime version only, and code that names the Bun global never takes it.
// Takes the fast path: plain code, no SDK import.
export async function main(n: number = 10) {
return Array.from({ length: n }, (_, i) => i * i)
}Flows reserve ahead
A flow knows what is coming. When it is claimed, and again when each loop starts, it asks its worker for enough warm Python runners for the burst — twice the loop’s parallelism, up to a ceiling — so the iterations after the first wave start with no boot at all. Measured on our stack, a loop iteration went from 101 to 45 ms median with no cold starts after the first wave.
A run’s detail shows the difference: a step that had to boot its runner carries a cold start mark with the time it cost. See Performance for every measured figure.
Tune it (self-hosted)
WARM_POOL_BASE— warm runners kept per language at rest (2 by default).0turns the pool off and every job boots its own runner.WARM_POOL_RESERVE_MAX— the most a flow may reserve on one worker (8 by default, about 110 MB of idle Python).0turns reservations off.SQL_POOL_MAX_PER_INTEGRATION— open connections per database connection per worker (4 by default).