Cubicle

Stop, hibernate and wake a Box

Stop or hibernate a Cubicle Box and wake it again with start or exec wake, covering stop versus hibernate, what survives each, automatic hibernation 60 minutes after start, hibernateAt, hibernation_failed with hibernationRetryAt, and restartRequired after a host reboot.

A running Box can be stopped or hibernated. Stopping shuts the guest down and keeps its disk. Hibernating also saves the Box's memory to its disk, so its processes carry on where they were when it wakes. A running Box also hibernates by itself 60 minutes after it starts. Box lifecycle describes every state.

Before you begin

  • Set up the SDK or the CLI as in the Quickstart. The examples use a running Box acme/job-1 (cubicle boxes create --org acme job-1 --wait). TypeScript snippets use const box = cubicle.boxes.ref("acme/job-1"), and curl snippets read a write key from CB_SDK_API_KEY and use jq.
  • You need a grant on the Box, or the owner or admin role in its organization. An API key needs write scope.

Choose stop or hibernate

StopHibernate
What happensThe guest is asked to shut down. After 15 s it is stopped by force.The vCPUs pause, and memory and device state are saved into the Box's disk image.
Memory and running processesLostKept. They continue when the Box wakes.
DiskKeptKept
Private IP address, grants and reserved resourcesKeptKept
Open SSH and network connectionsClosedClosed
Running execsEnd unknownEnd unknown
Next startCold bootResumes from saved memory
Snapshot or restoreAllowedNot allowed. Stop the Box first.
Available inTypeScript SDK, CLI, HTTP API, DashboardTypeScript SDK, HTTP API, Dashboard. The CLI has no hibernate command.

Hibernate when you want to pick up running work later, such as a dev server or a background job. Stop when you want a clean boot, or before you take a snapshot.

A free Omarchy Box (pooled: true) is the exception: while it is stopped or hibernated it gives up its vCPUs and memory, and it is deleted at expiresAt unless you start it.

Hibernate a Box

The Box's desired state must be running. A Box that is already hibernated is left as it is, and the request still succeeds.

const info = await box.hibernate() // waits until the Box is hibernated, up to 5 min
console.log(info.state) // => "hibernated"

The CLI cannot hibernate a Box. Use the SDK, the API or Hibernate in the Dashboard.

Stop a Box

const info = await box.stop() // waits until the Box is stopped, up to 5 min
console.log(info.state) // => "stopped"

Stopping a hibernated Box discards its saved memory and keeps its disk. The Dashboard calls this Discard saved memory.

Do not shut down or reboot from inside the Box. The VM exits instead of restarting, and the Box reports failed with "box exited unexpectedly; start it again". Start it to boot it again.

Automatic hibernation

A running Box hibernates 60 minutes after its current start first reports running, whatever it is doing: SSH sessions, execs and background jobs do not extend the hour, and you cannot turn automatic hibernation off or change the hour. hibernateAt in the Box's record says when it will happen (details).

const info = await box.info()
console.log(info.hibernateAt) // => "2026-11-05T11:02:17.000Z"

Every start begins a fresh hour. To get one for a running Box, start it again: it does not reboot, but SSH and private-network traffic pause until its Node applies the new generation. After automatic hibernation, exec requests fail with 409 conflict "box is not running" until you wake the Box.

Wake a Box

Starting a Box resumes it from saved memory if it is hibernated, and cold-boots it if it is stopped.

await box.start() // waits until SSH and exec can be used, up to 5 min

To wake the Box only when a command needs it, pass wake: true to exec; see Run commands.

In the Dashboard, a hibernated Box shows "Hibernated · Start resumes saved memory".

Check what survived

The kernel's boot ID changes on every boot, so it shows whether the Box resumed or booted again:

const bootId = ["cat", "/proc/sys/kernel/random/boot_id"]

const before = await box.exec(bootId)
await box.hibernate()
await box.start()
const afterResume = await box.exec(bootId)
console.log(afterResume.stdout === before.stdout) // => true: memory and processes survived

await box.stop()
await box.start()
const afterBoot = await box.exec(bootId)
console.log(afterBoot.stdout === before.stdout) // => false: a stop means a cold boot

Troubleshooting

  • SDK CubicleBoxError with code hibernation_failed, "box job-1 could not hibernate: …; the Controller retries at …": saving memory failed. The Box keeps running, its desired state returns to running, observed.error holds the error and hibernationRetryAt says when Cubicle tries again. It retries after 30 s, then doubles the delay up to 5 min, so you need not do anything. If you need the Box off now, stop it: cubicle boxes stop acme/job-1 --wait. Stopping it, or starting it for a fresh hour, ends the retries.

    import { CubicleBoxError } from "@cubicle/sdk"
    
    try {
      await box.hibernate()
    } catch (error) {
      if (error instanceof CubicleBoxError && error.code === "hibernation_failed") {
        console.log(error.box.observed?.error, error.box.hibernationRetryAt)
      }
    }
  • restartRequired: true, or 409 conflict "the box requires an explicit Start after a host reboot" on a hibernate: the Box's host rebooted and its memory is gone. Start the Box; see restartRequired: true.

  • A hibernated Box stays hibernated after a host reboot: a host reboot never resumes a hibernated Box. Start it.

  • state: failed after a start, with observed.error "Saved VM configuration is incompatible; Stop then Start for a cold boot": the host's QEMU version or CPU, or the Box's kernel or size, changed since it hibernated, so the saved memory cannot be loaded. Stop the Box, which discards the saved memory, then start it. In the SDK, start rejects with CubicleBoxError code box_failed. Any other failed resume whose error tells you to stop has the same fix.

  • 409 conflict "only a running box can hibernate": the Box's desired state is stopped. Start it first if you want to hibernate it.

  • SDK CubicleBoxError with code box_superseded, "box job-1 is now requested hibernated, not running": something else changed the Box's desired state while you waited, such as another client or automatic hibernation. Read the Box and decide again.

On this page