How Linux CPU Cgroups Limit Process Usage

Control Groups (cgroups) are a core Linux kernel feature designed to isolate, allocate, and monitor system resources among groups of processes. When managing CPU utilization, the kernel combines cgroup accounting with scheduler logic—specifically the Completely Fair Scheduler (CFS)—to enforce both proportional time-sharing and strict processing ceilings. This mechanism ensures that high-priority workloads remain responsive while preventing misbehaving or resource-heavy processes from starving the rest of the system.

Core Scheduler Mechanisms

The Linux kernel relies on two primary mechanisms within the CPU controller to limit usage: proportional shares (soft limits) and bandwidth control (hard limits).

1. Proportional Bandwidth (Shares and Weights)

Proportional sharing determines how CPU time is divided when multiple processes are actively competing for cycles. If the system is idle, a process using this mechanism can consume up to 100% of available CPU capacity.

2. CFS Bandwidth Control (Hard Limits)

CFS bandwidth control prevents a process from exceeding a specified absolute threshold, regardless of whether spare CPU capacity exists on the host. This mechanism operates on two main parameters: period and quota.

In cgroups v1, these are configured using:

In cgroups v2, these parameters are consolidated into a single file called cpu.max:

The Throttling Process

When a hard limit is configured, the kernel enforces it via throttling:

  1. Accounting: Each time a thread from the target cgroup is scheduled to run, the kernel tracks the CPU time it accumulates via timer interrupts and context switches.
  2. Quota Depletion: Once the aggregate runtime of all threads in the cgroup reaches the assigned quota before the period expires, the kernel flags the cgroup as throttled.
  3. Descheduling: Throttled processes are immediately removed from the CFS runqueue. Even if the system has idle cores, these processes cannot execute any instructions.
  4. Replenishment: When the next period begins (e.g., at the next 100ms interval), a timer interrupt resets the used quota, the cgroup transitions back to an unthrottled state, and its threads are requeued for execution.

Throttling statistics are recorded in cpu.stat, allowing administrators and container engines to track metrics such as nr_throttled (number of periods throttled) and throttled_time (total time spent blocked).

Processor Pinning with the Cpuset Subsystem

In addition to bandwidth-based throttling, Linux provides the cpuset cgroup controller. While the standard CPU controller dictates how much processor time a process receives, cpuset restricts where that execution occurs:

Combining CFS bandwidth control with cpuset isolates processes both temporally (limiting total execution time) and spatially (confining execution to designated hardware units), providing deterministic resource controls across modern Linux environments.