On Runtime, 400 interviews of 75 minutes cost about $17.85 a month, under 5 cents each. That includes stored snapshots for 20 questions. The figure uses the rates in effect on 26 October 2026. A sandbox started from a snapshot comes up with the question's repository, packages and even running services already in place. So the candidate can start coding immediately. Each candidate gets a Firecracker microVM of their own.
The short answer
Once per question, set up a sandbox and keep it as a snapshot. For each interview, start a copy and open a terminal for both people. The sandbox has no time limit, so an interview runs as long as it needs:
TypeScriptimport { Runtime } from "withruntime";const runtime = new Runtime();// Once per question: the starter repository with its dependencies installed.const setup = await runtime.sandboxes.create({ diskMiB: 8192 });await setup.files.upload("./questions/rate-limiter", "/workspace/task");await setup.exec("cd task && npm ci", { check: true, timeoutMs: 600_000 });const question = await setup.snapshot({ name: "q-rate-limiter", retentionDays: 365 });await setup.stop();// Each interview: a fresh copy of that machine.const interview = await runtime.sandboxes.create({ snapshot: question.id, name: "interview-2291", labels: { kind: "interview", question: "rate-limiter", candidate: "c-5120" },});// No time limit: the interview runs as long as it needs, and an open terminal keeps it awake.await interview.network.set({ internet: true, allow: ["registry.npmjs.org"] });const term = await interview.terminal({ cols: 120, rows: 32, onData: (bytes) => process.stdout.write(bytes), // fan out to both browsers});term.write("cd task && npm test\n");// ... at the end of the interview, collect results (below).Pythonfrom withruntime import Runtimeruntime = Runtime()setup = runtime.sandboxes.create(disk_mib=8192)setup.files.upload("./questions/rate-limiter", "/workspace/task")setup.exec("cd task && npm ci", check=True, timeout_ms=600_000)question = setup.snapshot(name="q-rate-limiter", retention_days=365)setup.stop()interview = runtime.sandboxes.create( snapshot=question["id"], name="interview-2291", labels={"kind": "interview", "question": "rate-limiter", "candidate": "c-5120"},)# No time limit: the interview runs as long as it needs.interview.network.set(internet=True, allow=["registry.npmjs.org"])term = interview.terminal(cols=120, rows=32)term.write("cd task && npm test\n")A snapshot keeps running processes. So a question that needs a database or an API mock can have it running before the candidate arrives. A snapshot is kept while you have credit. It is copied off its server immediately after it is taken.
Record the session as a timeline
Interviewers want to see how a candidate reached the answer, not only the final file. A file watch reports every create, write, rename and remove as it happens. Store each event with a timestamp and the file's new contents:
TypeScriptimport { Sandbox } from "withruntime";const sbx = await Sandbox.connect(process.env.INTERVIEW_SANDBOX_ID!);const timeline: { at: string; type: string; path: string; text?: string }[] = [];const watch = await sbx.files.watch( "/workspace/task", async (event) => { const text = event.type === "write" ? await sbx.files.readText(event.path) : undefined; timeline.push({ at: new Date().toISOString(), type: event.type, path: event.path, text }); }, { recursive: true, exclude: ["node_modules", ".git/**"] },);// ... when the interview ends:await watch.stop();console.log(timeline.length, "events recorded");Repeated writes to one file inside a batch arrive as one event with a count, so a save-on-every-keystroke editor does not flood the log. For a front-end question, the sandbox's desktop can also record the screen to MP4, stored on the sandbox's own disk (a desktop).
Grade with tests the candidate never saw
Keep the hidden tests out of the question's snapshot. When the interview ends, upload them and run them in the candidate's sandbox, with the internet off so the result depends on the code alone:
TypeScriptimport { Sandbox } from "withruntime";const sbx = await Sandbox.connect(process.env.INTERVIEW_SANDBOX_ID!);await sbx.network.off();await sbx.files.upload("./hidden-tests/rate-limiter", "/workspace/task/hidden");const result = await sbx.exec("npx vitest run hidden --reporter=json", { cwd: "/workspace/task", timeoutMs: 300_000,});await sbx.files.download("/workspace/task", "./archive/interview-2291");console.log(result.exitCode);await sbx.stop();The download keeps a copy of the candidate's final work for the hiring committee, and stopping the sandbox ends its billing.
Settings for a fair interview
| Question for your platform | Setting |
|---|---|
| May the candidate install packages? | network.allow with just the package registry, or network.off() |
| May they search the web or call an AI API? | Leave those hosts out of allow. The host enforces it, even against sudo |
| Does every candidate get the same machine? | Every interview starts from the same snapshot, size and image |
| What if the candidate's code hangs? | timeoutMs on each run. A run past the limit returns a timeout, with the output so far |
| Which languages? | Any that the image has. The interpreter adds Python, JavaScript, TypeScript, R, Java, Bash and Go |
| Who on the team can start interviews? | Owners, admins and developers; billing members cannot (teams) |
| Who did what? | The audit log records changes to keys, members and network rules. It is kept for 400 days |
What an interview platform needs
| Need | How Runtime covers it |
|---|---|
| A ready environment per question | Snapshots with processes, kept while you have credit |
| A shared terminal | terminal() over WebSocket; your back end sends its bytes to both people |
| A record of the session | files.watch events; desktop recording to MP4 |
| Hidden tests | Uploaded after the interview, run with the internet off |
| Isolation between candidates | A Firecracker microVM with its own kernel per interview |
| Sessions over an hour | Nothing to do: no time limit, and an open terminal keeps it running |
What it costs
Assume 400 interviews a month. Each keeps a 2 vCPU, 4 GiB sandbox running for 75 minutes. The candidate's builds and tests use 0.1 of a vCPU on average. The account keeps 20 question snapshots of 1 GB each:
- CPU
- 400 × 1.25 h × 0.1 vCPU × $0.025
- $1.25
- Memory
- 400 × 1.25 h × 4 GiB × $0.0075
- $15.00
- Snapshots
- 20 × 1 GB × $0.08
- $1.60
- Total
- $17.85
Runtime charges $0.025 per vCPU-hour of measured CPU and $0.0075 per GiB-hour of memory. It charges $0.08 per GB per 30-day month for a snapshot's own bytes. A block shared by two of your snapshots counts once (pricing).
Start
Terminalnpx withruntime sandboxes run --keep -- node --versionOpen the browser link that appears to approve the run. Then
runtime sandboxes snapshot <id> keeps that machine as a question's starting
point (CLI).
Related: coding playground, grade student code, online IDE on sandboxes, sandbox snapshots.
Facts on this page were checked on 26 October 2026.