# How to View Detailed Container Resource Usage in JSON Format with the Container CLI

> Learn how to view detailed container resource usage in JSON format. Monitor CPU, memory, network, and I/O metrics using the container stats command.

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

---

**Use `container stats --format json --no-stream` to output detailed CPU, memory, network, and block I/O metrics as a machine-readable JSON array.**

The `apple/container` repository provides a daemon-based container runtime that exposes resource metrics through the `stats` subcommand. When integrating with monitoring systems or processing container metrics programmatically, viewing detailed container resource usage in JSON format offers a structured alternative to the default human-readable table view.

## Prerequisites

Before querying resource usage, ensure you have:

- The Container CLI installed and configured
- The Container daemon running via XPC
- At least one running container to query (or access to the system containers)

## Enabling JSON Output Mode

The CLI implements **static JSON output** through the `--format json` flag combined with `--no-stream`. This configuration serializes an array of `ContainerStats` structs using Swift’s `JSONEncoder`, providing consistent field names and numeric values suitable for pipeline processing.

### Why You Must Use `--no-stream`

By default, the `stats` command operates in streaming mode, producing a continuously updating display similar to `top`. When you request JSON format, you must disable this behavior with `--no-stream` to receive a single snapshot that terminates after the initial data collection. Without this flag, the encoder would attempt to interleave JSON with screen-control sequences, resulting in malformed output.

## Technical Implementation Details

The JSON output flow traverses the client-daemon boundary through XPC, with serialization handled in the command layer.

### Command Parsing in ContainerStats.swift

In [`Sources/ContainerCommands/Container/ContainerStats.swift`](https://github.com/apple/container/blob/main/Sources/ContainerCommands/Container/ContainerStats.swift), the command definition declares the `--format` option using the `ListFormat` enum and the `--no-stream` boolean flag. Lines 34-38 define these options, while lines 45-50 implement the logic that detects when to invoke `runStatic()`:

- If `--format json` is specified **or** `--no-stream` is set, the command enters static mode
- Static mode gathers metrics once and exits immediately

### XPC Communication with ContainerAPIService

When `runStatic()` executes, it instantiates a `ContainerClient` and calls `client.stats(id:)` for each target container. This method communicates with the daemon’s XPC endpoint defined in [`Sources/Services/ContainerAPIService/Server/Containers/ContainersService.swift`](https://github.com/apple/container/blob/main/Sources/Services/ContainerAPIService/Server/Containers/ContainersService.swift) at line 790. The server-side `ContainersService.stats` method returns a `ContainerStats` struct populated with raw kernel metrics including CPU time, memory pages, and block device statistics.

### JSON Encoding and Rendering

After collecting stats, the command passes the array of `ContainerStats` objects to `Output.render(payload:format:)`. When `format == .json`, this helper uses `JSONEncoder` to serialize the data (pretty-printed if `--pretty` is supplied) and writes the result to stdout. The implementation in [`Sources/ContainerCommands/Container/ContainerStats.swift`](https://github.com/apple/container/blob/main/Sources/ContainerCommands/Container/ContainerStats.swift) lines 105-107 handles the final encoding step before output.

## Available JSON Fields

The JSON array contains objects with the following fields from the `ContainerStats` struct:

- `id` – Container identifier
- `cpuUsageUsec` – CPU usage in microseconds
- `memoryUsageBytes` – Current memory consumption
- `memoryLimitBytes` – Memory limit for the container
- `networkRxBytes` – Bytes received over network interfaces
- `networkTxBytes` – Bytes transmitted over network interfaces
- `blockReadBytes` – Total bytes read from block devices
- `blockWriteBytes` – Total bytes written to block devices
- `numProcesses` – Current process count

## Practical Examples

Fetch resource usage for all running containers as a JSON snapshot:

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

```

Query a specific container by name:

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

```

Generate pretty-printed JSON for a specific container ID:

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

```

Pipe the output to `jq` for filtering specific metrics:

```bash
container stats --format json --no-stream | jq '.[] | {id, memoryUsageBytes}'

```

## Summary

- Use **`container stats --format json --no-stream`** to view detailed container resource usage in JSON format
- The `--no-stream` flag is required to prevent continuous updates and ensure valid JSON output
- The implementation resides in [`Sources/ContainerCommands/Container/ContainerStats.swift`](https://github.com/apple/container/blob/main/Sources/ContainerCommands/Container/ContainerStats.swift) with XPC communication handled by `ContainersService.stats` at line 790
- The JSON output includes CPU, memory, network, block I/O, and process metrics defined in the `ContainerStats` struct
- Add `--pretty` for human-readable indentation during debugging

## Frequently Asked Questions

### Do I need to specify `--no-stream` every time I use JSON format?

Yes. According to the source code in [`ContainerStats.swift`](https://github.com/apple/container/blob/main/ContainerStats.swift), the command enters static mode only when `--format json` or `--no-stream` is explicitly provided. Without `--no-stream`, the command attempts to refresh the display continuously, which breaks JSON formatting by inserting terminal control sequences between data frames.

### What is the difference between streaming and static mode?

Streaming mode updates resource metrics in real-time using terminal screen refresh sequences, similar to the `top` command. Static mode, triggered by `runStatic()`, queries the daemon once via the `ContainersService.stats` endpoint, encodes the results immediately, and exits. Static mode is required for JSON output and automation scripts.

### Can I get pretty-printed JSON instead of compact output?

Yes. Append the `--pretty` flag to your command. The `Output.render(payload:format:)` method checks for this option and configures `JSONEncoder` with pretty-printing enabled, adding line breaks and indentation to the output while maintaining the same data structure.

### Where is the ContainerStats data structure defined?

The `ContainerStats` struct is defined in the `ContainerResource` module, specifically in [`Sources/ContainerResource/ContainerStats.swift`](https://github.com/apple/container/blob/main/Sources/ContainerResource/ContainerStats.swift). This type represents the wire format exchanged between the daemon and CLI, containing the raw numeric metrics for CPU, memory, network, and block I/O that eventually get serialized into your JSON output.