Skip to main content
Open-source BoxLite runs on hardware you own and manage; BoxLite Cloud runs on BoxLite’s resource pool, and you reach it with a URL and an API key over the same SDK. This page is the single place where those differences are enumerated. Every other Cloud page links here instead of restating them.

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 with box.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.
Choose Cloud when:
  • 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.
The two are not exclusive. The same SDK talks to both, so developing against a local box and running the same code against Cloud in production is a change of runtime handle, not a rewrite.

Porting existing open-source code to Cloud

Four edits cover almost every port:
  1. Swap the runtime handle to Boxlite.rest(BoxliteRestOptions(url, credential)).
  2. Change exec from varargs to args=[...].
  3. Replace the async with context manager with an explicit await rt.remove(box.id, force=True) in a finally block.
  4. 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
The volume in the second script is the part that carries state forward. Destroy the box and create another one against the same volume id, and /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