# How to Monitor Container Resource Usage with Container Stats: Real-Time Statistics Guide

> Learn to monitor container resource usage with container stats and real-time metrics. Get live CPU, memory, network, and I/O data for your containers.

- Repository: [Apple/container](https://github.com/apple/container)
- Tags: how-to-guide
- Published: 2026-06-13

---

**Use the `container stats` command to display live CPU, memory, network, and block I/O metrics for running containers, with support for both interactive streaming and static JSON output.**

The **apple/container** repository provides a Swift-based container management toolset that includes built-in resource monitoring capabilities. Understanding how to monitor container resource usage with container stats enables operators to observe live performance metrics without external tooling. The implementation spans three architectural layers, from the CLI front-end through XPC communication to the underlying runtime statistics.

## Architecture of the Container Stats Command

### CLI Front-End

The `ContainerStats` command in [`Sources/ContainerCommands/Container/ContainerStats.swift`](https://github.com/apple/container/blob/main/Sources/ContainerCommands/Container/ContainerStats.swift) handles user input parsing and output formatting. It supports two primary modes: **streaming** for real-time monitoring and **static** for single snapshots. The `run()` method evaluates flags such as `--format` and `--no-stream` to determine which execution path to invoke.

### Client-Server API

Communication flows through `ContainerClient`, which issues XPC calls to the daemon. The `stats(id:)` method retrieves a `ContainerResource.ContainerStats` struct containing raw metrics. This data model, defined in [`Sources/ContainerResource/Container/ContainerStats.swift`](https://github.com/apple/container/blob/main/Sources/ContainerResource/Container/ContainerStats.swift), encapsulates memory usage, CPU time, network I/O, block I/O, and process counts.

### Runtime Service

On the daemon side, `RuntimeService` (located in [`Sources/Services/RuntimeLinux/Server/RuntimeService.swift`](https://github.com/apple/container/blob/main/Sources/Services/RuntimeLinux/Server/RuntimeService.swift)) queries the container runtime via `container.statistics()`. It returns a `ContainerStatistics` structure that the client decodes into the Swift model used for display.

## How to Use Container Stats

### Real-Time Streaming Mode

By default, the command enters an alternate screen buffer and continuously refreshes metrics similar to the `top` utility.

```bash
container stats

```

The `runStreaming()` method handles this live display, clearing the screen and printing updated tables until you press **Ctrl-C**.

### Static Snapshot with JSON Output

For scripting and automation, use the `--no-stream` flag combined with `--format json`:

```bash
container stats --format json --no-stream

```

This invokes `runStatic()`, which enumerates containers via `client.list(...)`, collects statistics, and outputs a JSON array. The `collectStats()` method gathers two samples two seconds apart to calculate CPU percentages via `calculateCPUPercent()`.

### Targeting Specific Containers

Monitor individual containers by specifying their ID or name:

```bash
container stats my-web-app

```

Without `--no-stream`, this streams updates for only that container.

## Understanding the Metrics Output

The `container stats` command displays these key metrics derived from the `ContainerStats` struct:

- **CPU %**: Percentage of a full core used, computed from the delta between two `cpuUsageUsec` readings
- **Memory Usage / Limit**: Current consumption versus the container-configured limit
- **Network Rx/Tx**: Bytes received and transmitted across all interfaces
- **Block I/O**: Bytes read and written to block devices
- **PIDs**: Number of processes running inside the container

The `formatBytes(_:)` function converts raw byte values into human-readable KiB/MiB/GiB units, while `statsTable(_:)` builds the formatted table output.

## Example JSON Payload

When using `--format json`, the output matches the Swift model structure:

```json
[
  {
    "id": "e5f9a7c3b2d1",
    "memoryUsageBytes": 104857600,
    "memoryLimitBytes": 2147483648,
    "cpuUsageUsec": 12345678,
    "networkRxBytes": 5242880,
    "networkTxBytes": 1048576,
    "blockReadBytes": 262144,
    "blockWriteBytes": 131072,
    "numProcesses": 12
  }
]

```

These fields correspond directly to the properties in [`Sources/ContainerResource/Container/ContainerStats.swift`](https://github.com/apple/container/blob/main/Sources/ContainerResource/Container/ContainerStats.swift).

## Key Implementation Files

| File | Role |
|------|------|
| [`Sources/ContainerCommands/Container/ContainerStats.swift`](https://github.com/apple/container/blob/main/Sources/ContainerCommands/Container/ContainerStats.swift) | CLI command implementation with streaming and static logic |
| [`Sources/ContainerResource/Container/ContainerStats.swift`](https://github.com/apple/container/blob/main/Sources/ContainerResource/Container/ContainerStats.swift) | Data model for per-container metrics |
| [`Sources/Services/RuntimeLinux/Server/RuntimeService.swift`](https://github.com/apple/container/blob/main/Sources/Services/RuntimeLinux/Server/RuntimeService.swift) | Daemon-side statistics collection from the runtime |
| [`Sources/Services/ContainerAPIService/Server/Containers/ContainersService.swift`](https://github.com/apple/container/blob/main/Sources/Services/ContainerAPIService/Server/Containers/ContainersService.swift) | XPC service exposing the `stats(id:)` RPC |

## Summary

- The `container stats` command provides real-time visibility into container resource consumption across CPU, memory, network, and I/O metrics.
- **Streaming mode** (`runStreaming()`) offers an interactive, continuously updating display ideal for live debugging.
- **Static mode** (`runStatic()`) with `--no-stream` and `--format json` enables scriptable access to resource data.
- CPU percentages are calculated from two samples taken two seconds apart using `calculateCPUPercent()`.
- All metrics flow through the XPC-based `ContainerClient` API, with data models defined in the `ContainerResource` module.

## Frequently Asked Questions

### How does container stats calculate CPU percentage?

The `calculateCPUPercent()` function in [`ContainerStats.swift`](https://github.com/apple/container/blob/main/ContainerStats.swift) collects two samples of `cpuUsageUsec` approximately two seconds apart via `collectStats()`. It derives the percentage by comparing the delta in CPU microseconds against the elapsed time, giving you the percentage of a full CPU core being utilized.

### Can I monitor container resource usage without streaming updates?

Yes. Append the `--no-stream` flag to `container stats` to fetch a single snapshot. Combine this with `--format json` to receive machine-readable output suitable for logging or monitoring systems, as implemented in the `runStatic()` method.

### What is the difference between memory usage and memory limit in the output?

`memoryUsageBytes` shows the current resident set size of the container's processes, while `memoryLimitBytes` reflects the maximum memory configured for that container. The `ContainerStats` struct in [`Sources/ContainerResource/Container/ContainerStats.swift`](https://github.com/apple/container/blob/main/Sources/ContainerResource/Container/ContainerStats.swift) encapsulates both values, allowing you to calculate utilization percentages.

### Does the container stats command work with specific container names?

Yes. You can pass a container ID or name as an argument to `container stats` to filter output to that specific container. If you omit the `--no-stream` flag, the command will stream real-time updates for only that container rather than all running containers.