How to Monitor Container Resource Usage with Container Stats: Real-Time Statistics Guide
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 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, 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) 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.
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:
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:
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
cpuUsageUsecreadings - 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:
[
{
"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.
Key Implementation Files
| File | Role |
|---|---|
Sources/ContainerCommands/Container/ContainerStats.swift |
CLI command implementation with streaming and static logic |
Sources/ContainerResource/Container/ContainerStats.swift |
Data model for per-container metrics |
Sources/Services/RuntimeLinux/Server/RuntimeService.swift |
Daemon-side statistics collection from the runtime |
Sources/Services/ContainerAPIService/Server/Containers/ContainersService.swift |
XPC service exposing the stats(id:) RPC |
Summary
- The
container statscommand 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-streamand--format jsonenables 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
ContainerClientAPI, with data models defined in theContainerResourcemodule.
Frequently Asked Questions
How does container stats calculate CPU percentage?
The calculateCPUPercent() function in 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 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.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →