Runtime

How to run a coding playground for your users

Run each visitor's code in its own microVM sandbox with the internet off, a time limit per run, and a warm interpreter between runs.

On Runtime 20,000 playground sessions a month cost about $55.56, a quarter of a cent each, on 1 vCPU, 2 GiB sandboxes at the rates in force on 25 September 2026. Runtime bills the CPU the code uses, so a session where the visitor spends most of the time reading and typing costs little, and one interpreter covers Python, JavaScript, TypeScript, R, Java, Bash and Go, with gcc and g++ for C and C++.

The short answer

One sandbox per browser session, found again by name, with the network cut and a limit on every run:

TypeScriptimport { Sandbox } from "withruntime";type Language = "python" | "javascript" | "typescript" | "go" | "java" | "r" | "bash";export async function runSnippet(sessionId: string, language: Language, code: string) {  const sbx = await Sandbox.getOrCreate(`play-${sessionId}`, {    vcpu: 1,    memoryMiB: 2048,    idlePauseSeconds: 300, // pause five minutes after the last run    network: { internet: false },    maxCostMicros: 100_000, // refuse a create whose first lease could cost more than 10 cents    labels: { kind: "playground" },  });  const cell = await sbx.interpreter.run(code, { language, timeoutMs: 10_000 });  return {    status: cell.status, // "ok", "error" or "timeout"    stdout: cell.stdout,    stderr: cell.stderr,    error: cell.error?.traceback ?? null,  };}console.log(await runSnippet("s-1", "python", "total = sum(range(10))\nprint(total)"));console.log(await runSnippet("s-1", "python", "print(total * 2)")); // state carries over
Pythonfrom withruntime import Sandboxdef run_snippet(session_id: str, language: str, code: str) -> dict:    sbx = Sandbox.get_or_create(        f"play-{session_id}",        vcpu=1,        memory_mib=2048,        idle_pause_seconds=300,  # pause five minutes after the last run        network={"internet": False},        max_cost_micros=100_000,  # refuse a create whose first lease could cost more than 10 cents        labels={"kind": "playground"},    )    cell = sbx.interpreter.run(code, language=language, timeout_ms=10_000)    return {"status": cell["status"], "stdout": cell["stdout"], "stderr": cell["stderr"],            "error": (cell["error"] or {}).get("traceback")}print(run_snippet("s-1", "python", "total = sum(range(10))\nprint(total)"))print(run_snippet("s-1", "python", "print(total * 2)"))  # state carries over

Variables persist between runs, the way a notebook works, so a visitor's second run can use what the first defined. To give a clean slate, stop the sandbox and the next run makes a new one.

Languages, and how each one runs

Language How the playground runs it First use in a sandbox
Python 3.12 Interpreter, state kept between runs Ready; NumPy, pandas, matplotlib included
JavaScript, TypeScript Interpreter, on Node.js 24 Ready
Bash Interpreter Ready
Go Interpreter; keeps functions, types and imports Installed once, about 35 seconds
Java Interpreter Installed once, about 35 seconds
R Interpreter; plots return as PNG Installed once, about 90 seconds
C, C++ gcc or g++ through exec, then the binary Ready
Rust rustup baked into a custom image Build the image once

The install times were measured on 23 September 2026. To skip them, build an image with those languages and start playground sandboxes from it (custom images).

C and C++ go through a file and a fixed command, so the visitor's code is data, never part of the shell line:

TypeScriptimport { Sandbox } from "withruntime";await using sbx = await Sandbox.create({ network: { internet: false } });await sbx.files.write("/workspace/main.c", '#include <stdio.h>\nint main(){puts("hi");}\n');const build = await sbx.exec(["gcc", "-O2", "-o", "main", "main.c"], { timeoutMs: 20_000 });const run = build.exitCode === 0 ? await sbx.exec(["./main"], { timeoutMs: 5_000 }) : build;console.log(run.exitCode, run.stdout, run.stderr);

Stop a playground from being abused

A public playground runs code from strangers. Each guard below is enforced outside the code's reach:

Abuse Guard
Escaping to your servers A Firecracker microVM with its own kernel per session
Sending traffic out internet: false, enforced on the host; root in the sandbox cannot undo it
An infinite loop timeoutMs per run; the run returns as a timeout with the output so far
Flooding the page with output Each result holds at most 64 KiB of stdout and 64 KiB of stderr
Filling memory or disk The sandbox's own memoryMiB and diskMiB; other sessions are unaffected
Running up your bill maxCostMicros per create, a daily spending limit on the key, pause when idle
Too many sessions at once Creates past the account limit wait for room instead of failing

Runtime's acceptable use policy applies to what your visitors run too, so keep the internet off unless a lesson needs it; when one does, allow only that host with network.allow.

Stream output as it prints

For programs that print over time, stream to the browser instead of waiting:

TypeScriptimport { Sandbox } from "withruntime";await using sbx = await Sandbox.create({ network: { internet: false } });await sbx.interpreter.run(  "import time\nfor i in range(3):\n    print(i, flush=True)\n    time.sleep(1)",  {    timeoutMs: 10_000,    onStdout: (text) => process.stdout.write(text), // send each chunk over your WebSocket  },);

What a coding playground needs

Need How Runtime covers it
Many languages Seven interpreter languages, plus gcc and g++
A session that remembers Named sandboxes with getOrCreate; variables persist between runs
Fast first run 351 ms median from create to first Python result, 24 September 2026
Cheap idle sessions Measured CPU while running; idlePauseSeconds pauses quiet ones
Isolation between visitors One microVM per session
Nothing leaves Internet off per sandbox

What it costs

Take 20,000 sessions a month. Each keeps a 1 vCPU, 2 GiB sandbox running 10 minutes, idle pause included, with the visitor's runs using 40 CPU-seconds, and is stopped when the session ends:

TextCPU:     20,000 × 40 s / 3,600 × $0.025            = $5.56Memory:  20,000 × 10 min / 60 × 2 GiB × $0.0075    = $50.00Total:                                               $55.56

A session's CPU never bills below the floor of a twentieth of a vCPU, which over 10 minutes is 30 CPU-seconds, so 40 is above it. Runtime charges $0.025 per vCPU-hour of measured CPU and $0.0075 per GiB-hour of memory (pricing).

Start

Terminalnpx withruntime sandbox run --trial -- node -e 'console.log(6 * 7)'

Approve the browser link once. runtime sandbox run-code <id> - --lang go < main.go runs a file in any interpreter language from a terminal (CLI).

Related: online IDE on sandboxes, coding interview platform, grade student code, run untrusted LLM code, Go in a sandbox.

Facts on this page were checked on 25 September 2026.