microVM lifecycle
Every sandbox microVM is in one of seven states, and the runtime scheduler drives every transition under a per-VM lock; only the leader replica mutates. Pause, idle suspend and fork change what you pay for and what survives, and the guarantees differ per transition. The API, SDK calls and costs are in Sandbox lifecycle.
Swipe sideways to pan. Tap a state or an arrow.
States
Section titled “States”| State | Meaning |
|---|---|
PENDING |
The scheduler accepted the request and awaits placement. |
SPAWNING |
A node is assigned and the VM is bootstrapping. Also the state of a resume or fork child while the manager restores it. |
RUNNING |
The harness is reporting heartbeats. Holds one concurrent-VM quota slot. |
DRAINING |
Graceful shutdown started. A pause in progress is persisted here with the scheduler:pausing marker, so a crash never reloads it as PAUSED. |
PAUSED |
Snapshotted and stopped. Holds no quota slot; snapshot storage is kept. Resumable. |
FAILED |
Spawn or health failure; the reason is in the StatusEvent. |
TERMINATED |
Resources released. |
Transitions
Section titled “Transitions”| From | To | Trigger |
|---|---|---|
| start | PENDING |
POST /v1/runtime/schedule |
PENDING |
SPAWNING |
Placed on a node |
SPAWNING |
RUNNING |
First harness heartbeat |
SPAWNING |
FAILED |
Spawn fails |
RUNNING |
DRAINING |
Pause, idle timeout or delete |
DRAINING |
PAUSED |
Snapshot and stop succeeded |
DRAINING |
RUNNING |
Stop failed; the VM keeps its slot |
DRAINING |
TERMINATED |
Drained after delete |
PAUSED |
SPAWNING |
Resume or auto-resume |
SPAWNING |
PAUSED |
Restore failed; resumable again |
RUNNING |
SPAWNING (children) |
Fork x N |
Sequences
Section titled “Sequences”Schedule
Section titled “Schedule”POST /v1/runtime/schedulecarries an AgentSpec: image, isolation, limits, egress, secrets and optionalidleTimeoutSecs.RuntimeScheduler.Scheduleruns. Over the tenant’s quota, the control plane answers 402.- The scheduler places the VM (
PENDING, thenSPAWNING), choosing the node by warm pool, region, fair share, cost and health. Spawn { spec, handle }: the manager writesspawn.jsonto the read-only cert drive and boots the VM.- The harness heartbeats every 5 s. PID 1 is up, so the VM is
RUNNING. Each beat carrieshas_active_execandlast_activity_unix_ms. - The control plane returns
{ vm_id }. The sandbox is addressable by that id from here on.
Idle suspend and auto-resume
Section titled “Idle suspend and auto-resume”- The guest reports
has_active_exec = false: no workload or exec child is alive. The activity tracker stamps when the last one exited. - The idle sweeper ticks every 10 s, on the leader only. A VM is eligible when it is
RUNNING, hasidle_timeout_secs > 0, and has been idle longer than the timeout. Snapshot { vm_id }runs through the same crash-safe path as an operator pause, markedscheduler:idle-pausing.Stopremoves the VM from the node. Its snapshot stays.- The VM becomes
PAUSEDwith reason “auto-suspended (idle timeout)”, and its quota slot is freed. - A later
POST .../vms/{id}/execreachesensureVMRunning, which calls Resume becauseidle_timeout_secs > 0.FailedPreconditionmeans the VM is already running. Spawn { restore_snapshot_id }reserves quota first (402 if over) and restores under the samevm_id.- The original exec proceeds, and the control plane audits
auto_resume.
The sweeper does not update the control plane’s shadow row, so GET /v1/runtime/vms shows an auto-suspended VM as running. A VM paused manually is never auto-resumed: exec answers 409.
Pause and resume
Section titled “Pause and resume”POST .../vms/{id}/pause. Only aRUNNINGVM can be paused.- The scheduler persists the snapshot id before
Stop, then marks the VMDRAINING(scheduler:pausing). Stop { reason: paused }. If it fails, the VM returns toRUNNINGand keeps its slot.PAUSEDplussnapshot_idreturns. Exactly one of the RPC or reconciliation releases the quota slot.POST .../vms/{id}/resumerunsTryReserveTenantVMs, thenSPAWNING(scheduler:resuming).Spawnrestores from the snapshot under the samevm_id. A failed spawn leaves the VMPAUSED.- The restored guest takes a new incarnation’s certificate and exec token, so credentials frozen into the snapshot are refused.
Fork x N
Section titled “Fork x N”POST .../vms/{id}/fork { count }, withcountfrom 1 toPAL_MAX_FORK_COUNT(default 100, ceiling 1000).- The control plane issues one agent identity per child. Inheriting the source’s would let N sandboxes act as one.
- The scheduler reserves N slots, all or nothing, before any snapshot I/O.
Snapshot { keep_running }: a running source keeps running; a paused source forks from its pause snapshot.Spawnruns N times with newvm_ids, at mostPAL_FORK_CONCURRENCYat a time (default 16). A child that fails is reported and its slot released.- The manager hard-links the read-only
memfile into each jail, so pages are shared through the host page cache (MAP_PRIVATEcopy-on-write) until a guest writes. - The response is
forks [{ vmId, state, error? }]; each child isRUNNINGorFAILED.
Reference
Section titled “Reference”| Item | Value |
|---|---|
| Harness heartbeat | every 5 s; stale after 30 s |
| Idle sweeper tick | 10 s, for VMs with idleTimeoutSecs > 0 |
| Fork count | 1 to 100 by default, ceiling 1000; spawned 16 at a time |
| Paused VM | holds no quota slot; snapshot storage kept |
| Manually paused VM | never auto-resumed: exec answers 409 |