Side by side
What the table compresses
Virtualization moves, it does not disappear. Self-hosting puts the virtualization requirement on your host, which is why BoxLite fails to start a box on machines without KVM or Hypervisor.framework. On Cloud that requirement lives in the resource pool, so your client can be any machine that can make HTTPS requests — including CI runners and nested VMs. Storage is the difference that breaks silently. Every other row in this table produces a visible error if you get it wrong. A host bind mount does not: in REST mode the mount is accepted and ignored, so your code runs and your data is simply not there. Replace host bind mounts with a managed volume before you port. Volumes covers creating one and mounting it. Snapshots and clones do not carry over. If your self-hosted code saves disk state withbox.snapshot, clones a box, or exports one to an archive, that part does not run on Cloud — the hosted service has those four capabilities disabled. Keep state you need to survive a box on a volume instead, which is the durable path on Cloud anyway.
A Cloud box has a lifecycle policy; a self-hosted box does not. Cloud can stop a box when it goes idle, resume it when you reach for it again, and delete it after it has been stopped for a while. Set the policy in the console, or from code with auto_stop and auto_delete (both in seconds, 0 to disable) and auto_resume. The defaults differ by route: the console starts at a 15-minute idle stop, while a box created over the API gets no auto-stop unless you ask for one — see Boxes.
Images are prepared for you. Because image operations are not supported over REST, you do not pull on Cloud. Pick one of the console’s base images, or the default ghcr.io/boxlite-ai/boxlite-agent-base:v0.1.0, and let the shared Linux base images that come with a Boxes-scoped key do the rest.
Which should I use?
Self-host when:- You already run machines with virtualization capacity, and adding boxes costs you nothing new.
- You need host bind mounts — the box must read and write a directory on the same machine as your process.
- You need local image operations, such as pulling or inspecting images from the CLI.
- You want zero external dependency: no account, no network egress to a control plane, no third party in the failure path.
- Your machines have no hardware virtualization — laptops under a corporate policy, most managed CI runners, nested VMs.
- You want an agent to stay reachable without operating servers yourself: storage that outlives the box, and a lifecycle that stops it when idle and wakes it on access.
- You want to scale box count without capacity planning, by changing a plan instead of provisioning hosts.
- You want per-box resource ceilings enforced for you across a multi-tenant workload.
Porting existing open-source code to Cloud
Four edits cover almost every port:- Swap the runtime handle to
Boxlite.rest(BoxliteRestOptions(url, credential)). - Change
execfrom varargs toargs=[...]. - Replace the
async withcontext manager with an explicitawait rt.remove(box.id, force=True)in afinallyblock. - Replace host bind mounts with a managed volume.
Before: a local box on your own machine
local_box.py
After: the same job on Cloud
cloud_box.py
/data/notes.txt is still there.
Do not send path_prefix to Cloud
This one catches people who came from the open-source reference server. That server mounts its routes under a prefix, so the client must pass path_prefix="default" — see Manage remote sandboxes over REST. Cloud serves the SDK REST API without a prefix, so you pass only url and credential. Carry a path_prefix over from working self-hosted code and your requests will not land where you expect.
Troubleshooting a port
Next
- Cloud quickstart — create a key and run your first command end to end.
- What is BoxLite Cloud — the runtime model and what Cloud adds.
- Python SDK reference — the full signatures, types, and defaults shared by both runtimes.

