docs/sandboxes/metrics.mdx
Query resource usage for a running sandbox: CPU, memory, and more. Get a single point-in-time snapshot, or open a streaming subscription that delivers updates at a fixed interval.
OCI sandboxes also expose optional upper filesystem fields for capacity dashboards: guest-visible upper_used_bytes / upper_free_bytes when the protected bundled-kernel reporter is available and fresh, plus host-observed upper_host_allocated_bytes when the writable upper image can be inspected from the host. SDKs surface those as nullable fields (Option, null, None, or nil) because custom kernels and non-OCI roots may not provide them.
let metrics = sb.metrics().await?; println!("CPU: {:.1}%, Mem: {} MB", metrics.cpu_percent, metrics.memory_bytes / 1024 / 1024);
```typescript TypeScript
const metrics = await sb.metrics();
console.log(`CPU: ${metrics.cpuPercent.toFixed(1)}%, Mem: ${Math.floor(metrics.memoryBytes / 1024 / 1024)} MB`);
m = await sb.metrics()
print(f"CPU: {m.cpu_percent:.1f}%, Mem: {m.memory_bytes // 1024 // 1024} MB")
metrics, err := sb.Metrics(ctx)
fmt.Printf("CPU: %.1f%%, Mem: %d MB\n", metrics.CPUPercent, metrics.MemoryBytes/1024/1024)
Subscribe to metric updates at a regular interval. Each update arrives as a separate event.
<CodeGroup> ```rust Rust use std::time::Duration; use futures::StreamExt;let mut stream = sb.metrics_stream(Duration::from_secs(1)); while let Some(m) = stream.next().await { let m = m?; println!("CPU: {:.1}%, Mem: {} MB", m.cpu_percent, m.memory_bytes / 1024 / 1024); }
```typescript TypeScript
for await (const m of await sb.metricsStream(1000)) {
console.log(`[${m.timestamp.toISOString()}] CPU: ${m.cpuPercent.toFixed(1)}%`);
}
async for m in await sb.metrics_stream(interval=1.0):
print(f"[{m.timestamp_ms}] CPU: {m.cpu_percent:.1f}%")
stream, err := sb.MetricsStream(ctx, time.Second)
defer stream.Close()
for {
metrics, err := stream.Recv(ctx)
if err != nil {
return err
}
if metrics == nil {
break
}
fmt.Printf("CPU: %.1f%%\n", metrics.CPUPercent)
}
Get the latest metrics for every running sandbox at once. Useful for dashboards or capacity planning.
<CodeGroup> ```rust Rust use microsandbox::all_sandbox_metrics;let all = all_sandbox_metrics().await?;
```typescript TypeScript
import { allSandboxMetrics } from "microsandbox";
const all = await allSandboxMetrics();
from microsandbox import all_sandbox_metrics
all_metrics = await all_sandbox_metrics()
all, err := m.AllSandboxMetrics(ctx)
Fleet snapshots only include sandboxes whose runtime process is actually alive. A runtime that crashed without cleanup used to keep reporting its last sample as if the sandbox were running; readers now detect the dead owner and retire the entry on first read.
The Rust SDK additionally exposes reports: metrics joined with catalog context for presentation. A report resolves the CPU and memory allocations from the sandbox's active config (so live resizes are reflected), and carries a state field: Running, Stalled (runtime alive but no sample within three sampling intervals), or Exited (the preserved terminal sample of a stopped sandbox). This is what msb metrics renders.
use microsandbox::{all_sandbox_metrics_reports_local, sandbox_metrics_report_local};
// All sandboxes; pass true to include exited ones.
let reports = all_sandbox_metrics_reports_local(&local, false).await?;
for r in &reports {
println!("{} [{:?}] {:.2} cores of {:?}", r.name, r.state, r.metrics.cpu_percent / 100.0, r.cpus);
}
// One sandbox by name, in any state (unlike `Sandbox::metrics`, which
// errors when the sandbox is not running).
let report = sandbox_metrics_report_local(&local, "my-app").await?;
Report APIs for TypeScript, Python, and Go will follow.