Runtime

How to read a sandbox's CPU and memory metrics

Call sbx.metrics({ range: "1h" }): latest is the newest reading and points the series, measured by the sandbox's host.

On Runtime the CPU metric is the same reading the bill is made from. The host measures each running sandbox's CPU time once a minute, and Runtime charges $0.025 per active vCPU-hour of that measured CPU, with a floor of 50 millicores (pricing). So the chart that shows a sandbox idling also shows why it costs little: a 2 vCPU, 4 GiB sandbox that waits costs $0.03125 an hour, and $0.08 with both CPUs busy. Metrics, events and export cost nothing extra (metrics and webhooks).

Read them

TypeScriptimport { Sandbox } from "withruntime";await using sbx = await Sandbox.create();await sbx.exec("python3 -c 'sum(i * i for i in range(10**8))'", { timeoutMs: 120_000 });const m = await sbx.metrics({ range: "15m" });console.log(m.latest?.cpuPercent, m.latest?.memoryBytes);for (const p of m.points) console.log(p.at, p.cpuCores, p.cpuPeakPercent, p.memoryPeakBytes);
Pythonfrom withruntime import Sandboxwith Sandbox.create() as sbx:    sbx.exec("python3 -c 'sum(i * i for i in range(10**8))'", timeout_ms=120_000)    m = sbx.metrics(range="15m")    latest = m["latest"]    if latest:        print(latest["cpuPercent"], latest["memoryBytes"])    for point in m["points"]:        print(point["at"], point["cpuCores"], point["memoryPeakBytes"])
Terminalnpx withruntime sandbox metrics <id> --range 6h

The same readings are charts on the sandbox's page in your account, under Sandboxes, and an agent reads them with the runtime_sandbox_metrics MCP tool.

What each field means

Field Meaning
cpuPercent CPU in use as a percent of all the sandbox's vCPUs, 0 to 100
cpuCores The same, as a number of cores
cpuPeakPercent The busiest interval between two readings inside the bucket
memoryBytes Memory the sandbox's machine holds, as its host measures it
memoryPeakBytes The most it held inside the bucket
latest The newest reading, or null when there is none in the last 15 minutes

range chooses the window, and each point sums one bucket:

range Bucket Kept for
15m 10 seconds 24 hours
1h 20 seconds 24 hours
6h 2 minutes 24 hours
24h 8 minutes 24 hours
7d, 30d 1 hour 30 days

Size a sandbox from its readings

A sandbox's size is vcpu and memoryMiB, and you choose them. The readings say whether you chose well:

  • Memory. Memory is billed on what you reserve, $0.0075 per GiB-hour. If the largest memoryPeakBytes over a week of runs is 1.2 GiB, a 2 GiB sandbox does the job that a 4 GiB one did, for half the memory charge. The response also carries memoryLimitBytes to compare against.
  • CPU. CPU is billed on use, so extra vCPUs cost nothing while idle. A cpuPeakPercent near 100 during builds or tests means more vcpu would finish sooner; the bill follows the work done.
TypeScriptimport { Sandbox } from "withruntime";const sbx = await Sandbox.connect("<sandbox id>");const week = await sbx.metrics({ range: "7d" });const peak = Math.max(0, ...week.points.map((p) => p.memoryPeakBytes));console.log(  `peak ${(peak / 2 ** 30).toFixed(2)} GiB of ${(week.memoryLimitBytes / 2 ** 30).toFixed(0)} GiB`,);

For what you were actually charged, per resource, runtime usage and GET /v1/usage give the settled figures.

Send them to your own dashboards

An OpenTelemetry export pushes every sandbox's readings as OTLP gauges, about every 30 seconds, to Grafana, Honeycomb, Datadog, New Relic or any endpoint that takes OTLP over HTTP:

TypeScriptimport { Runtime } from "withruntime";const runtime = new Runtime();await runtime.otel.create({  endpoint: "https://api.honeycomb.io",  headers: { "x-honeycomb-team": process.env.HONEYCOMB_KEY ?? "" },  signals: ["metrics"],});

The gauges are runtime.sandbox.cpu.utilization, runtime.sandbox.cpu.usage, runtime.sandbox.memory.usage and runtime.sandbox.memory.limit, with one resource per sandbox carrying its id, name, vCPUs and region. An account can have three exports (OpenTelemetry export).

Mistakes and how Runtime handles them

  • Reading cpuPercent as per core. It is a share of all the sandbox's vCPUs. On a 2 vCPU sandbox, 50 means one core busy; cpuCores says 1.
  • Expecting readings from a paused sandbox. A paused or stopped sandbox has no new readings, and its earlier ones stay. latest is null once nothing has been read for 15 minutes.
  • Looking for last month's detail. Each minute's reading is kept 24 hours, and hourly averages and peaks 30 days. Export them to keep more.
  • Code written for E2B. Its getMetrics() works through withruntime/e2b and reads these same values; diskUsed is null.

Start

Terminalnpx withruntime sandbox run --trial --keep -- python3 -c 'print(6 * 7)'

New accounts get 50 free sandbox hours, no card. Then run runtime sandbox metrics <id> on the sandbox it kept.

Facts on this page were checked on 25 September 2026.