# How Container Manages Resource Limits and Monitors Usage with Stats: A Complete Guide

> Learn how Container manages resource limits and monitors usage with stats. Discover CPU, memory, and storage enforcement and live metrics for your containerized applications.

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

---

**Container uses a declarative `Resources` struct to define CPU, memory, and storage limits, propagates them to the runtime daemon for cgroup enforcement, and exposes live usage metrics through a dedicated stats endpoint.**

The `apple/container` repository provides a lightweight sandboxing framework for isolating workloads on macOS and Linux. Understanding how to constrain compute resources and observe consumption patterns is critical for production deployments. This guide examines the data-driven model that translates high-level configuration into kernel-enforced limits while providing real-time observability via HTTP routes.

## Defining Resource Limits in ContainerConfiguration

The foundation of resource management lies in the **`ContainerConfiguration.Resources`** struct defined in [`Sources/ContainerResource/Container/ContainerConfiguration.swift`](https://github.com/apple/container/blob/main/Sources/ContainerResource/Container/ContainerConfiguration.swift). This **Codable** structure allows developers to specify compute constraints through JSON, YAML, or native Swift code.

### The Resources Struct Fields

The struct exposes four key parameters that control sandbox consumption:

- **`cpus`** – Integer count of virtual CPU cores allocated to the sandbox.
- **`memoryInBytes`** – RAM limit expressed as an integer in bytes.
- **`storage`** – Optional persistent storage quota for the container filesystem.
- **`cpuOverhead`** – Additional cores reserved for VM overhead, such as guest agents and hypervisor processes.

### Default Values and Configuration Sources

When unspecified, the framework applies sensible defaults: **4 CPU cores**, **1 GiB of RAM**, and **1 overhead core**. Because the struct conforms to `Codable`, limits can be injected via configuration files, CLI flags, or programmatically in Swift before sandbox creation.

## Propagating Limits to the Runtime Daemon

Configuration declarations transition to enforced limits through the runtime service layer. In [`Sources/Services/RuntimeLinux/Server/RuntimeService.swift`](https://github.com/apple/container/blob/main/Sources/Services/RuntimeLinux/Server/RuntimeService.swift), the container runtime constructs a low-level configuration object that maps directly to cgroup parameters.

The translation occurs through direct assignment to the **`czConfig`** object:

```swift
// RuntimeLinux/Server/RuntimeService.swift
czConfig.cpus = config.resources.cpus
czConfig.cpuOverhead = config.resources.cpuOverhead
czConfig.memoryInBytes = config.resources.memoryInBytes

```

The underlying Apple-Linux container-runtime daemon receives these values and configures the appropriate cgroup or hypervisor settings. This ensures the sandbox cannot exceed its allocated resources for the duration of its lifecycle.

## Monitoring Usage with the Stats Endpoint

Live resource consumption is exposed through a dedicated HTTP route defined in [`Sources/Services/Runtime/RuntimeClient/RuntimeRoutes.swift`](https://github.com/apple/container/blob/main/Sources/Services/Runtime/RuntimeClient/RuntimeRoutes.swift). The runtime daemon collects per-sandbox metrics from operating system interfaces—primarily cgroup files on Linux—and returns them as structured JSON.

```swift
// Services/Runtime/RuntimeClient/RuntimeRoutes.swift
/// Get resource usage statistics for the sandbox.
/// Returns a `SandboxStats` JSON payload.

```

### The SandboxStats Model

The response payload decodes into a **`SandboxStats`** model containing:

- CPU utilization percentages.
- Memory RSS (resident set size) and working-set size.
- I/O read/write counters.

These metrics reflect actual consumption against the declared limits, enabling capacity planning and runtime observability.

### Querying Stats Programmatically

Swift clients retrieve statistics through the asynchronous API. The following example demonstrates configuring resources, launching a sandbox, and querying live metrics:

```swift
import ContainerResource
import ContainerAPI

// 1️⃣ Build a configuration with explicit limits
let resources = ContainerConfiguration.Resources(
    cpus: 2,
    memoryInBytes: 512.mib(),   // 512 MiB
    storage: 5.gib(),           // 5 GiB persistent storage
    cpuOverhead: 1
)

let cfg = ContainerConfiguration(
    id: "my-app",
    image: ImageDescription(name: "my-app:latest"),
    process: ProcessConfiguration(entrypoint: ["/usr/bin/my-app"])
)
cfg.resources = resources          // inject the limits

// 2️⃣ Launch the sandbox
let client = try await ContainerClient()
let sandbox = try await client.createSandbox(with: cfg)

// 3️⃣ Query live statistics
let stats = try await client.getStats(for: sandbox.id)
print("CPU %:", stats.cpuPercent)
print("Memory used:", stats.memoryUsage.bytes, "bytes")
print("IO read:", stats.ioRead.bytes, "bytes")

```

### CLI Equivalent

For command-line workflows, the `container` CLI exposes flags that map directly to the same configuration struct:

```bash

# Create a container with explicit limits

container run \
  --cpus 2 \
  --memory 512m \
  --storage 5g \
  my-app:latest

# Retrieve live stats

container stats my-app

```

## Machine-Level Resource Management

For container-machine objects, the framework mirrors this pattern using **`MachineResources`** defined in [`Sources/Services/MachineAPIService/Client/MachineBundle.swift`](https://github.com/apple/container/blob/main/Sources/Services/MachineAPIService/Client/MachineBundle.swift). Machine creation APIs forward these limits to the runtime identically, and the same stats endpoint can be queried for a machine’s sandbox.

## Summary

- **Resource limits** are declared through the `ContainerConfiguration.Resources` struct in [`ContainerConfiguration.swift`](https://github.com/apple/container/blob/main/ContainerConfiguration.swift), supporting CPU, memory, storage, and overhead parameters.
- **Runtime enforcement** occurs when [`RuntimeService.swift`](https://github.com/apple/container/blob/main/RuntimeService.swift) maps configuration values to the `czConfig` object, which the daemon translates into cgroup constraints.
- **Live monitoring** is available via the stats endpoint defined in [`RuntimeRoutes.swift`](https://github.com/apple/container/blob/main/RuntimeRoutes.swift), returning `SandboxStats` with CPU, memory, and I/O metrics gathered from cgroup files.
- **Machine sandboxes** use an identical resource model via [`MachineBundle.swift`](https://github.com/apple/container/blob/main/MachineBundle.swift), ensuring consistent behavior across standard containers and virtual machines.

## Frequently Asked Questions

### How do I set resource limits when creating a container?

You define a `ContainerConfiguration.Resources` struct with your desired `cpus`, `memoryInBytes`, `storage`, and `cpuOverhead` values, then assign it to your configuration's `resources` property before calling `createSandbox`. Alternatively, use the CLI flags `--cpus`, `--memory`, and `--storage` with the `container run` command according to the apple/container source code.

### What metrics are available through the Container stats endpoint?

The `SandboxStats` model returned by the stats endpoint provides CPU utilization percentages, memory RSS (resident set size), working-set size, and I/O read/write counters. These metrics are gathered from cgroup files on Linux and exposed through the HTTP route defined in [`RuntimeRoutes.swift`](https://github.com/apple/container/blob/main/RuntimeRoutes.swift).

### Where does Container enforce the resource limits?

Enforcement occurs in the underlying Apple-Linux container-runtime daemon. When [`RuntimeService.swift`](https://github.com/apple/container/blob/main/RuntimeService.swift) copies resource values to the `czConfig` object, the daemon translates these into appropriate cgroup or hypervisor settings that kernel-enforce the constraints for the entire sandbox lifecycle.

### Do container machines use the same resource management approach?

Yes. Container machines utilize the `MachineResources` struct in [`MachineBundle.swift`](https://github.com/apple/container/blob/main/MachineBundle.swift), which mirrors the standard `Resources` model. These limits propagate to the runtime identically, and you query machine statistics using the same `getStats` endpoint and CLI commands.