How to Reduce Cold Starts with Warm Runners
Cold-start latency is the gap between a job queuing and actually running. Warm runner pools keep machines ready so that gap shrinks to seconds.
Every job that waits for a runner to boot, install tooling, and warm caches pays a cold-start tax before any real work. Warm pools pre-provision runners with the toolchain and caches already in place.
1. Understand where cold-start time goes
Cold start is boot plus toolchain install plus cache restore. Measure the gap between created_at and started_at across jobs to size the problem.
# per-job queue time
gh api repos/OWNER/REPO/actions/runs/RUN_ID/jobs \
--jq '.jobs[] | {name, started: .started_at, created: .created_at}'2. Keep a warm pool
A warm pool holds pre-booted runners with the toolchain already installed, so a queued job is picked up immediately. Latchkey managed runners maintain warm pools so typical pickup is seconds, not the multi-minute boot of a cold self-hosted machine.
3. Pre-warm caches on the image
Bake or pre-restore dependency caches onto the warm runner so the first step is not a cold cache download. A warm pool plus a hot cache removes both halves of the cold-start tax.
4. Right-size the warm pool to demand
Too small and bursts still cold-start; too large and you pay for idle. Latchkey scales the pool to your job pattern and self-heals failed warm instances so the pool stays healthy.
Key takeaways
- Cold start is boot plus toolchain install plus cache restore.
- Warm pools keep runners pre-booted so jobs start in seconds.
- Pre-warm caches on the image to remove the second half of cold-start.