# How to give every user their own cloud dev environment Give each user a named sandbox that pauses when idle and wakes on the next request. Their files, memory and processes are kept between sessions. **On Runtime, a developer's environment costs about $1.80 a month** when it runs two hours a working day and sleeps the rest. Runtime bills the CPU that the sandbox uses, and a paused sandbox pays only for storage. The working is below. It is kept while you have credit. ## The short answer Name each environment after its user. `getOrCreate` returns that user's sandbox, woken if it paused, or creates it the first time: ```ts check import { Sandbox } from "withruntime"; export async function devEnvironment(userId: string) { const sbx = await Sandbox.getOrCreate(`dev-${userId}`, { labels: { kind: "dev", user: userId }, diskMiB: 16_384, idlePauseSeconds: 900, // pause after 15 minutes with no request }); if (!sbx.info.reused) { await sbx.exec("git clone https://github.com/your-org/your-repo.git app", { check: true, timeoutMs: 300_000, }); } return sbx; } ``` ```python check from withruntime import Sandbox def dev_environment(user_id: str): sbx = Sandbox.get_or_create( f"dev-{user_id}", labels={"kind": "dev", "user": user_id}, disk_mib=16_384, idle_pause_seconds=900, # pause after 15 minutes with no request ) if not sbx.info.get("reused"): sbx.exec("git clone https://github.com/your-org/your-repo.git app", check=True, timeout_ms=300_000) return sbx ``` The next day, the same call returns the same sandbox, with the same files. Any server or REPL left running is still running. A name is unique in the account while its sandbox can still run, so two requests for one user never make two environments. ## How the user gets in | Way in | How | | -------------------- | -------------------------------------------------------------------------------------- | | A shell | `runtime sandboxes ssh dev-alice`, or `sbx.terminal()` in your own web terminal | | VS Code or JetBrains | `runtime sandboxes ssh config --install`, then connect to host `dev-alice.runtime` | | A local port | `runtime sandboxes port-forward dev-alice 5432` for a database, debugger or dev server | | A browser tab | A private HTTPS preview of the dev server's port | | An agent | The same sandbox through the SDK, the CLI or Runtime's MCP server | Everything goes through Runtime's API with the user's key. The sandbox opens no port to the internet ([SSH and editors](/docs/editors)). A request of any of these kinds wakes a paused sandbox. A browser that visits a shared port sees a short "Waking up" page that reloads itself. ## Show the running app Start the dev server with `spawn`. It keeps running after your call returns. Then share its port: ```ts check import { Sandbox } from "withruntime"; const sbx = await Sandbox.getOrCreate("dev-alice", { idlePauseSeconds: 900 }); await sbx.spawn("cd app && npm run dev -- --port 3000"); const preview = await sbx.previews.create(3000); console.log(preview.urlWithToken); // a link that carries its token, for the user ``` ```python check from withruntime import Sandbox sbx = Sandbox.get_or_create("dev-alice", idle_pause_seconds=900) sbx.spawn("cd app && npm run dev -- --port 3000") preview = sbx.previews.create(3000) print(preview["urlWithToken"]) # a link that carries its token, for the user ``` A preview is private by default. A request needs its token. `previews.rotate(port)` rejects every token issued so far. ## Always on, or asleep when idle Pick per environment: - **`idlePauseSeconds`** (default 300; 60 to 86,400) pauses the sandbox after that long with nothing happening. Nothing happening means no request, no command or terminal running, no open connection, no traffic and no CPU use. You pay for running time only while the sandbox is in use, and for paused storage in between. - **`persistent: true`** keeps a paid sandbox running, idle or not, for as long as the account has credit. Set a cap with `maxTotalCostMicros`. Any stopped sandbox keeps its disk until you delete it, so `restart()` brings a user's machine back. - **A volume** is a disk that outlives any one sandbox. Attach it at `/data` to keep work separate from the machine ([storage](/docs/storage)). ```ts check import { Sandbox } from "withruntime"; const lead = await Sandbox.getOrCreate("dev-lead", { persistent: true, maxTotalCostMicros: 20_000_000, // at most $20 over its life }); await lead.update({ idlePauseSeconds: 0 }); ``` ## What a per-user environment needs | Need | How Runtime covers it | | ------------------------ | ------------------------------------------------------------------------------------------ | | One environment per user | Names unique per account; `getOrCreate` finds or makes it | | Nothing lost overnight | Pause keeps files, memory and running processes while you have credit | | Fast return | The next request wakes it, with memory and processes | | Low idle cost | Paused storage at $0.08 per GB per 30-day month; no compute while paused | | A full Linux machine | Ubuntu 24.04, `sudo`, Python, Node.js, Bun, gcc; `sudo enable-docker` for Compose | | The team's toolchain | A [custom image](/docs/images) from the repository's own Dockerfile | | Users kept apart | A Firecracker microVM with its own kernel for each user | | Team access | Owner, admin, developer and billing roles, with an audit log ([teams](/docs/teams)) | ## What it costs Take one developer's 2 vCPU, 4 GiB environment. It runs 2 hours a day on 22 working days, which is 44 hours a month. It uses 0.3 of a vCPU on average while it runs. It is paused for the other 676 hours, with 2 GB of its own disk and memory stored: ``` CPU: 44 h × 0.3 vCPU × $0.025 = $0.33 Memory: 44 h × 4 GiB × $0.0075 = $1.32 Paused: 2 GB × $0.08 × 676 h / 720 h = $0.15 Total: $1.80 ``` On those assumptions, a team of 50 costs about $90 a month. The paused size is the disk and memory blocks that only the sandbox owns. It is measured when the sandbox pauses ([pricing](/docs/pricing#paused-storage)). Every new account gets 100 free hours of a 1 GB machine in its first 30 days, with no card. Sandboxes without credit keep a pause for seven days at no charge. ## Start ```bash no-run npx withruntime sandboxes run --keep -- git --version ``` The first run prints a link to approve in your browser. `--keep` keeps the sandbox and prints how to run more in it. Then use the [JavaScript](/docs/javascript#sandboxes-by-name) or [Python](/docs/python#sandboxes-by-name) SDK as above. Related: [pause and resume a sandbox](/how-to/pause-and-resume-a-sandbox), [coding agent sandbox](/use-cases/coding-agent-sandbox), [preview apps an agent builds](/use-cases/preview-agent-built-apps), [run Docker in a sandbox](/how-to/run-docker-in-a-sandbox). Facts on this page were checked on 26 October 2026.