> ## Documentation Index
> Fetch the complete documentation index at: https://docs.microsandbox.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Metrics

> Monitor sandbox resource usage

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:

* `upper_used_bytes` and `upper_free_bytes` — guest-visible usage, reported when the bundled-kernel reporter is available and fresh.
* `upper_host_allocated_bytes` — host-observed allocation for the writable upper image, reported when the host can read it.

SDKs surface these as nullable fields (`Option`, `null`, `None`, or `nil`) because custom kernels and non-OCI roots may not provide them.

<Note>
  Need continuous shipping to Grafana, Datadog, Prometheus, or any other OTel-compatible backend? See [`msb-metrics`](/observability/msb-metrics), a sidecar binary that reads the same data and ships it over OTLP.
</Note>

## Point-in-time

<CodeGroup>
  ```rust Rust theme={null}
  use microsandbox::Sandbox;

  let metrics = sb.metrics().await?;
  println!("CPU: {:.1}%, Mem: {} MB", metrics.cpu_percent, metrics.memory_bytes / 1024 / 1024);
  ```

  ```typescript TypeScript theme={null}
  const metrics = await sb.metrics();
  console.log(`CPU: ${metrics.cpuPercent.toFixed(1)}%, Mem: ${Math.floor(metrics.memoryBytes / 1024 / 1024)} MB`);
  ```

  ```python Python theme={null}
  m = await sb.metrics()
  print(f"CPU: {m.cpu_percent:.1f}%, Mem: {m.memory_bytes // 1024 // 1024} MB")
  ```

  ```go Go theme={null}
  metrics, err := sb.Metrics(ctx)
  fmt.Printf("CPU: %.1f%%, Mem: %d MB\n", metrics.CPUPercent, metrics.MemoryBytes/1024/1024)
  ```
</CodeGroup>

## Streaming

Subscribe to metric updates at a regular interval. Each update arrives as a separate event.

<CodeGroup>
  ```rust Rust theme={null}
  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 theme={null}
  for await (const m of await sb.metricsStream(1000)) {
      console.log(`[${m.timestamp.toISOString()}] CPU: ${m.cpuPercent.toFixed(1)}%`);
  }
  ```

  ```python Python theme={null}
  async for m in await sb.metrics_stream(interval=1.0):
      print(f"[{m.timestamp_ms}] CPU: {m.cpu_percent:.1f}%")
  ```

  ```go Go theme={null}
  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)
  }
  ```
</CodeGroup>

## Fleet-wide metrics

Get the latest metrics for every running sandbox at once. Useful for dashboards or capacity planning.

<CodeGroup>
  ```rust Rust theme={null}
  use microsandbox::all_sandbox_metrics;

  let all = all_sandbox_metrics().await?;
  ```

  ```typescript TypeScript theme={null}
  import { allSandboxMetrics } from "microsandbox";

  const all = await allSandboxMetrics();
  ```

  ```python Python theme={null}
  from microsandbox import all_sandbox_metrics

  all_metrics = await all_sandbox_metrics()
  ```

  ```go Go theme={null}
  all, err := m.AllSandboxMetrics(ctx)
  ```
</CodeGroup>
