Skip to main content

Pattern 1: one always-on sandbox per project

This pattern is the simplest, and each project is fully isolated.
  1. Make a sandbox for each user project with --no-auto-stop.
  2. Clone or copy the user’s code into it.
  3. Run the user’s dev server.
  4. Expose the dev server.
  • Only the people you give the _token URL to can open it.
  • The preview stays up while the sandbox runs.
Use this pattern when the project has real traffic, or when the user pays you enough to cover the cost.

Pattern 2: one always-on sandbox per user

This pattern is like pattern 1. The difference is that one sandbox holds all the projects of one user.
  • Each project has its own folder and its own port.
  • You install a small daemon in the sandbox. It multiplexes the agent sessions.
  • This works well for up to 5 to 10 fullstack projects per user.
The cost is about $26/month for each user, not for each project. Be careful with isolation: the projects of one user share a machine.

Pattern 3: stop and resume around usage

This pattern is the cheapest, and each sandbox is isolated. Most platforms end up with it. The sandbox runs only while the user works.
  1. The user sends a message.
  2. If the sandbox of the user is stopped, run boat resume on it. This takes a few seconds.
  3. At the same time, start your daemon and the preview again.
  4. Send the message to the agent.
  5. When the agent finishes, wait a short countdown.
  6. Run boat stop. The stop makes a snapshot of the file system and pauses billing.
See Snapshots.

When the user is done for good

A stop is a pause. A delete is the end.
  • To delete, use DELETE /sandboxes/{sandboxId}, boat delete, or the ⋯ menu in the dashboard.
  • A delete force-stops the sandbox. It permanently deletes the snapshots that only this sandbox uses.
  • Boat keeps snapshot data that a fork, a resume or a named template still reads.
  • You cannot undo a delete. You cannot resume the sandbox after it.
Connect delete to an explicit “delete my project” action. Never connect it to an idle timeout. If the user can come back, stop the sandbox instead. See Snapshots.

When a stop is refused

A stop saves the disk of the sandbox first. If that save fails, Boat refuses the stop. The sandbox keeps running, so the user does not lose work. You do not pay for that time. The meter pauses by itself from the first failed attempt. A stuck sandbox never shows on your invoice, and you have nothing to claim back. See When a stop is refused. What your backend sees:
  1. Treat a refused stop as retryable, not as fatal.
  2. The stop stays pending. Boat retries it until a save succeeds.
  3. Then the sandbox stops by itself.
  4. Boat also sends an email to the sandbox owner.
To stop the sandbox now, pass force.
  • The sandbox stops with its last successful snapshot.
  • Everything written after that snapshot is lost.
  • You cannot undo it. Offer it only after a stop has already failed.
  • Without force, the sandbox stops this way by itself after 3 days of failed saves. Boat sends an email to the owner before that.

Cost

To charge this cost to your users, read the meter of each sandbox for the billing period.
  • Use GET /sandboxes/{sandboxId}/usage, or boat usage <id>.
  • It works on running and stopped sandboxes.
  • It counts exactly what Boat charged your balance for that sandbox.
See Per-sandbox usage.

Two improvements

  • No preview downtime. Publish successful builds to a static host or a CDN. The sandbox is only for the agent and the dev preview. Production traffic never depends on a running sandbox.
  • No agent latency. Run a copy of the agent without tools on your own server. It answers immediately and stalls while the sandbox resumes. For a working implementation, see optibox.