Lifecycle & Hibernation
Create, run, hibernate, resume, and destroy a sandbox, and the cost model behind each transition.
A sandbox moves through five states, and the transitions between them are the only operations that cost money. An idle hibernated sandbox costs nothing on the runner side.
This page walks each transition and the cost model behind it.
create() exec()
┌──────────────► running ◄────────┐
│ │ │
│ hibernate() │
│ ▼ │
│ hibernated │
│ │ │
│ resume() │
│ ▼ │
│ running ──────────┘
│
└─ destroy() ─► destroyedCreate a sandbox
It boots a microVM with its own kernel. Defaults: 1 vCPU, 1 GiB RAM, 4 GiB writable scratch disk that grows on write.
import { Isorun } from 'isorun'
const isorun = new Isorun()
const sandbox = await isorun.create({ image: 'python:3.12-slim' })
console.log(sandbox.id) // run<...>
console.log(sandbox.createMs) // server-side create duration in msWrap the work in try { … } finally { destroy() } so the sandbox is always freed:
const sandbox = await isorun.create({ image: 'python:3.12-slim' })
try {
await sandbox.exec("python3 -c 'print(42)'")
} finally {
await sandbox.destroy()
}Hibernate a sandbox
Hibernation pauses the sandbox, persists its state, and releases active runtime resources. The runID stays valid, so the user sees a paused workspace they can come back to. The runner only spends resources when the sandbox is actively running, so a hibernated sandbox is essentially free.
const sandbox = await isorun.create({ image: 'python:3.12-slim' })
await sandbox.exec('pip install numpy pandas') // setup work
// User closes their laptop. Hibernate the workspace.
await sandbox.hibernate()
// Hours later, the user comes back…
await sandbox.resume()
// State is identical to what it was at hibernate time:
// the pip-installed packages are still there, the cwd is preserved,
// and any background processes the user started are still running.
await sandbox.exec("python3 -c 'import numpy; print(numpy.__version__)'")What survives a hibernate/resume cycle:
- Filesystem state. Anything you wrote to the scratch disk is intact.
- Memory state. Every page the VM had loaded is preserved, including in-memory caches, JIT-compiled bytecode, and database working sets.
- Process state. Background processes the user started before
hibernation are still running at the same PIDs after resume. A
long-running
node server.js, ajupyter notebookkernel, an SSH agent, they all survive. - Open file descriptors and listen sockets. The VM's network stack is re-attached to a fresh network interface with a new guest IP. Listen sockets and the kernel's TCP stack survive cleanly.
The VM gets a new guest IP on resume, so any ESTABLISHED outbound TCP connection from before hibernation is reset. Code that holds a long-lived connection (a database pool, a streaming HTTP client) must reconnect after resume().
Resume a sandbox
Resume restores a hibernated sandbox. The same runID is reused across hibernate/resume cycles, so client code that holds a reference to a sandbox doesn't need to track a new identity.
Destroy a sandbox
Destroy frees the sandbox permanently, including any hibernation snapshot on disk. It returns measured resource usage, these are the numbers you're billed on.
const stats = await sandbox.destroy()
console.log(stats.cpuMs) // CPU time used
console.log(stats.memPeakBytes) // peak RSS
console.log(stats.uptimeMs) // wall-clock from create to destroy
console.log(stats.costCents) // exact billed amount in centsAuto-destroy timeout
Every sandbox has an idle timeout (default 300 seconds, configurable
per-create via timeoutSec). When the timer fires, the sandbox is
destroyed. Use sandbox.setTimeout(seconds) to extend it during a
long-running workflow, pass 0 to disable.
Tip
Reach for hibernation when you want the workspace to persist but the VM resources released. The user-facing experience is "always on"; the runner-facing cost is "only when you're actively running."
Next steps
- Create and execute, the basic create/exec/destroy loop.
- Checkpoints and rollback, persist state across regions with snapshots.
- Pricing, the per-second billing model.