Skip to content
Guides · Agent cookbook

How Do I Tell if a Sandbox Resume Restored Memory or Cold-Booted?

Updated October 27, 2026 .md

Short answer: Read memoryRestored after every resume. true means memory came back and processes kept running. false means the sandbox booted from disk, and resumeReason says why (cpu_mismatch, resized, no_memory_snapshot or restore_failed). Inside the guest, compare /proc/sys/kernel/random/boot_id with a saved copy. On a cold boot, restart services and re-warm caches.

A resume usually restores the VM's memory, so your processes carry on (see pause and resume with memory). Sometimes it boots from disk instead. Your files are kept, but nothing is running. An agent that assumes its dev server, REPL or cache is still there will then fail in confusing ways. This page shows how to tell the two cases apart and what to do in each.

The signals at a glance#

We ran both cases on a small sandbox on 2026-10-27: a plain sbx stop --wait + sbx resume, then a stop and sbx resume --type default.

Signal Memory resume Cold boot (resize)
memoryRestored (API, sbx info --json) true false
resumeReason null "resized"
CLI note on sbx resume (terminal) none Resumed from disk: files are intact, running processes were not kept (resized).
/proc/sys/kernel/random/boot_id unchanged new value
/proc/uptime keeps counting (39.4 s) starts again (2.8 s)
Process started before the stop alive, same PID gone
File in /tmp still there gone
File in your home directory still there still there
Resume time 1.4 s 3.4 s

memoryRestored is null before a sandbox's first resume, and on forks. When it's false, resumeReason is one of the four values in the snapshots docs: cpu_mismatch (no machine with the sandbox's CPU type was free in time), resized, no_memory_snapshot or restore_failed. We could only force resized on prod. The other three depend on the platform's state, so treat any false the same way.

Check from outside: the API or CLI#

The orchestrator that resumed the sandbox should check right away. With the CLI:

sbx resume $id >/dev/null
read restored reason < <(sbx info $id --json | jq -r '.sandbox | "\(.memoryRestored) \(.resumeReason // "none")"')
echo "restored=$restored reason=$reason"
restored=false reason=resized

With the REST API, the same two fields are on the sandbox object:

curl -sS https://sandboxer.com/api/v1/sandboxes/$id \
  -H "Authorization: Bearer $SANDBOXER_API_KEY" | jq -c '.sandbox | {memoryRestored, resumeReason}'
{"memoryRestored":true,"resumeReason":null}

The ready event that sbx resume --json prints already carries the full sandbox, including memoryRestored, so a script that reads the event stream needs no extra call. A human-readable sbx resume prints a note only for a cold boot. It prints nothing extra when memory was restored.

Check from inside: the boot id#

Code running in the sandbox can't see the API fields without a key, and it may not know a resume happened at all. The Linux kernel gives each boot a random id in /proc/sys/kernel/random/boot_id. A memory resume keeps the same kernel, so the id stays the same. A cold boot gets a new one. Save it and compare:

mkdir -p ~/bin && cat > ~/bin/boot-check <<'EOF'
#!/bin/sh
# Prints warm or cold, then remembers this boot.
now=$(cat /proc/sys/kernel/random/boot_id)
last=$(cat ~/.last-boot-id 2>/dev/null)
echo "$now" > ~/.last-boot-id
if [ "$now" = "$last" ]; then echo warm; else echo cold; fi
EOF
chmod +x ~/bin/boot-check

Keep the saved copy in your home directory, not /tmp. In our cold boot, /tmp came back empty. What we saw across the three runs:

first run                           cold   (no saved id yet)
after sbx resume                    warm   uptime 7.08 s, server PID 554 still listed
after sbx resume --type default     cold   uptime 2.74 s

The ids themselves, from another run:

before stop:          45b7df5a-4d1f-4c77-932f-ce80599c9927
after memory resume:  45b7df5a-4d1f-4c77-932f-ce80599c9927
after resize resume:  edfaa86e-d636-43c9-af19-f63aac2433d4

Uptime is a weaker signal. A low uptime suggests a cold boot, but a sandbox that ran for only a few seconds before its stop also has a low uptime after a memory resume (7.08 s above). Use the boot id.

What to do in each case#

You see What's still there Do this
memoryRestored: true / same boot id Processes, open files, in-memory caches, shell state Nothing for processes. Re-check anything that depends on elapsed time (next section)
memoryRestored: false / new boot id Files in your home directory and on disk, enabled systemd units Start what you started by hand (dev servers, REPLs, tmux), rebuild in-memory caches, rerun warm-up requests, and treat jobs that were running as lost
resumeReason: "cpu_mismatch" and you need the processes Same as above Next time, resume with sbx resume --require-memory. It waits up to 30 minutes for a matching machine instead of booting from disk

An agent loop can make the restart step automatic:

if [ "$restored" != true ]; then
  sbx exec $id --detach "python3 -m http.server 8000"   # start your service again
  # then rerun your warm-up step, e.g. a first request or a cache build
fi

A better fix is to need no restart step at all. Run long-lived services as enabled systemd units, so a cold boot starts them for you (see services that should always run). Then the check only decides whether to re-warm caches and redo lost work.

--require-memory can't be combined with --type: a new size always boots from disk. The CLI's cold-boot note still suggests --require-memory after a resized resume. Ignore it in that case. Moving to a smaller size isn't supported yet (create a new sandbox and copy your files). Our sbx resume --type small after moving to default returned 400 type_too_small ("The sandbox's data does not fit the small disk.").

Timers after a memory resume#

The wall clock is corrected on resume, so date and time.time() are right. Elapsed-time clocks may not count all of the stopped time. In our test on 2026-10-27, a 2-minute stop moved the guest's monotonic clock forward by only about 62 seconds:

before stop    real 1793097486.33  mono 3.46   boot 3.46
after resume   real 1793097610.91  mono 65.17  boot 65.17

The wall clock moved 124.6 s, and the monotonic clock (and CLOCK_BOOTTIME) 61.7 s. A sleep 90 started just before the stop fired 152 seconds of wall time after it started, 28 seconds after the resume. In a shorter, 32-second stop, the monotonic clock moved about the same as the wall clock. Don't rely on either behavior. If a deadline, timeout or lease must hold across a stop, compare wall-clock timestamps (date +%s, time.time()) rather than monotonic ones, or recheck it when your boot check runs.

FAQ#

Which is more reliable, memoryRestored or the boot id?#

Both told the truth in every run. Use memoryRestored from the orchestrator, because it also gives the reason. Use the boot id inside the sandbox, where you have no API key or don't know a resume happened.

Can I force a cold boot to test my recovery code?#

Yes. Stop the sandbox, then resume it at a larger size with sbx resume $id --type default. It reports memoryRestored: false and resumeReason: "resized". Moving to a smaller size isn't supported yet, so test on a throwaway sandbox.

Do files survive a cold boot?#

Files on the disk do, including your home directory. /tmp was empty after our cold boot, so keep anything you need in your home directory.

Does an idle auto-pause behave the same way?#

Yes. A wake after idle auto-pause is a resume, so it sets memoryRestored and resumeReason the same way.

More guides

Top AI sandbox platforms for code execution in 2026, ranked

For running AI-written code we rank Sandboxer, Freestyle and E2B first: each gives code its own VM with an API or SDK and can pause with memory. Pick Daytona for Windows or GPUs, Modal or Northflank for GPUs at scale, E2B or Northflank to run in your own cloud, and Vercel Sandbox if your app lives on Vercel.

Read the guide
Best sandboxes for running coding agents (Claude Code, Codex, Gemini CLI) in 2026, ranked

For coding agents we rank Sandboxer first: a full Ubuntu VM with Claude Code and Codex preinstalled, Docker, and stop-and-resume that keeps the agent's session in memory. Freestyle and Amp Orbs also keep memory across pauses. Pick E2B for prebuilt agent templates on open source, Docker Sandboxes for free local runs, and Codespaces if you live in GitHub.

Read the guide
Best Daytona sandbox alternatives in 2026, ranked

The best Daytona alternatives depend on why you're switching. For a full Linux microVM on every sandbox with memory-saving stop and Docker, we rank Sandboxer first. E2B suits open source and self-hosting, Modal massive short-job fleets, Northflank bring-your-own-cloud with GPUs, and Vercel Sandbox apps on Vercel.

Read the guide
Best E2B alternatives in 2026, ranked

If you're leaving E2B for longer sessions or a fuller machine, we rank Sandboxer first, then Freestyle: both give each sandbox a full Linux VM that keeps memory across pauses, with Docker and no short session cap. Pick Daytona for Windows or GPUs, Northflank for bring-your-own-cloud, and stay on E2B if you need open source.

Read the guide