When you open a chat in Mana, you're not talking to a server. You're talking to a tiny Linux VM that exists for the duration of your session and disappears afterwards.
Why per-session sandboxes
Running an LLM coding agent means trusting it to:
- Read and write files
- Install dependencies
- Spawn subprocesses to compile and test
Doing that on a shared host is risky. Doing it inside a Fly Machine costs us a few cents per session and gives every user their own isolated rootfs, network namespace, and process tree.
The lifecycle
- Acquire — iOS asks the main server for a sandbox. The server claims a pre-warmed Fly machine atomically (
SELECT … FOR UPDATE SKIP LOCKED). - Connect — iOS opens a WebSocket directly to the sandbox on port 3000. The main server is no longer in the request path for the chat stream.
- Run — the sandbox drives Claude Code via the Agent SDK; MCP tools call back to the main server for persistence.
- Suspend — after 3 minutes idle (or 11 minutes wall clock), the sandbox tar.gz's the workspace to R2 and shuts down.
What this buys you
- Speed — the chat stream has one fewer network hop than the typical AI app
- Safety — a runaway agent affects only the current user's machine
- State — your workspace is durable; pick up where you left off across sessions
For more on the architecture, see the docs.