cgroups

Namespaces give processes an isolated view of the system. cgroups (control groups) limit how much they can use. Without cgroups, one container could consume all CPU, RAM, or disk I/O on a host, starving everything else. cgroups are why docker run --memory 512m --cpus 2 actually works.

What Are cgroups?

How do cgroups limit resources? cgroups organize processes into a hierarchy of groups. Each group has controllers — one for CPU, one for memory, one for I/O. You set limits on a group, and the kernel enforces them for every process in that group. When a container is created, its processes are placed in a cgroup and limits are set. The container can never exceed those limits, no matter what runs inside.
# cgroups are exposed as a filesystem ls /sys/fs/cgroup/ # cgroup v2 (unified): # cgroup.controllers cgroup.procs cpu.max memory.max io.max ... # cgroup v1 (legacy — separate directory per controller): # /sys/fs/cgroup/cpu/ # /sys/fs/cgroup/memory/ # /sys/fs/cgroup/blkio/ # Check which version you're running: stat -fc %T /sys/fs/cgroup/ # tmpfs = cgroup v1 # cgroup2fs = cgroup v2 (modern, unified)

cgroup v1 vs cgroup v2

cgroup v1cgroup v2
StructureSeparate hierarchy per controllerSingle unified hierarchy
Process membershipProcess can be in different groups per controllerProcess in exactly one group
Thread-level controlNoYes (thread mode)
Pressure notificationsBasicPSI (Pressure Stall Information)
Default sinceLinux 2.6.24 (2008)Linux 4.5+ (2016), default ~2021
Docker supportFullFull (Docker 20.10+)

Creating and Using cgroups (v2)

# Create a cgroup by making a directory mkdir /sys/fs/cgroup/myapp # The kernel auto-populates it: ls /sys/fs/cgroup/myapp/ # cgroup.procs cpu.max memory.max io.max memory.current cpu.stat ... # Add a process to the cgroup: echo $$ > /sys/fs/cgroup/myapp/cgroup.procs # $$ = current shell PID — now this shell and children are in the cgroup # Set memory limit (512MB): echo $((512 * 1024 * 1024)) > /sys/fs/cgroup/myapp/memory.max # Set CPU limit (50% of one core): # Format: "quota period" in microseconds echo "50000 100000" > /sys/fs/cgroup/myapp/cpu.max # 50000/100000 = 50% of 1 CPU # Check current memory usage: cat /sys/fs/cgroup/myapp/memory.current # 45678592 ← bytes currently used # Kill cgroup (remove all processes, delete dir): rmdir /sys/fs/cgroup/myapp

How Docker Uses cgroups

# Start a limited container: docker run -d --name myapp --memory 512m --cpus 2 nginx # Docker creates a cgroup automatically: cat /proc/$(docker inspect myapp --format '{{.State.Pid}}')/cgroup # 0::/system.slice/docker-abc123.scope ← cgroup v2 path # Find the cgroup: ls /sys/fs/cgroup/system.slice/docker-abc123.scope/ # memory.max cpu.max cgroup.procs ... # Verify limits: cat /sys/fs/cgroup/system.slice/docker-abc123.scope/memory.max # 536870912 ← 512MB in bytes cat /sys/fs/cgroup/system.slice/docker-abc123.scope/cpu.max # 200000 100000 ← 200ms quota per 100ms period = 2 CPUs # --memory-swap controls total memory+swap: docker run --memory 512m --memory-swap 1g myimage # swap = 1g - 512m = 512m of swap allowed

PSI — Pressure Stall Information

How do you know if a cgroup is actually resource-constrained? PSI (Pressure Stall Information) measures the fraction of time processes are stalled waiting for a resource. Available in cgroup v2. A CPU pressure of 20% means processes spent 20% of time waiting for CPU. Kubernetes uses PSI to detect and evict memory-pressured pods before they OOM.
# Per-cgroup pressure stats: cat /sys/fs/cgroup/myapp/memory.pressure # some avg10=5.00 avg60=2.00 avg300=1.00 total=12345 # full avg10=1.00 avg60=0.50 avg300=0.20 total=5678 # "some" = at least one task stalled # "full" = all tasks stalled (more severe) # avg10/60/300 = 10s/60s/5min averages (percentage) cat /sys/fs/cgroup/myapp/cpu.pressure cat /sys/fs/cgroup/myapp/io.pressure

Frequently Asked Questions

What will I learn here?

This page covers the core concepts and techniques you need to understand the topic and progress confidently to the next lesson.

How should I use this page?

Start with the overview, then follow the section links to deepen your understanding. Use the table of contents on the right to jump to specific sections.

What should I read next?

Use the navigation below to continue to the next lesson or explore related topics.