control groups
/ see-groups /
Namespaces decide what a group of processes can SEE; control groups - cgroups for short - decide how much it can USE. A cgroup is a Linux kernel mechanism that gathers a set of processes together and applies limits and accounting to their resource consumption: how much CPU time, how much memory, how much disk and network bandwidth they may take. If namespaces are the walls of a container, cgroups are the metering and the circuit breakers - the second essential half of building a container.
You use cgroups through a special filesystem mounted at /sys/fs/cgroup, organised as a tree of directories. Each directory is a group; you put a process into it by writing its PID into the group's cgroup.procs file, and you set limits by writing numbers into control files. For example, writing to memory.max caps how much memory the group may use - exceed it and the kernel reclaims pages or, if it cannot, invokes the out-of-memory killer on a process in that group, not on the rest of the system. CPU controllers let you grant a group a weight (a fair share when busy) or a hard ceiling (no more than 30% of one core, say). The kernel also keeps accounting - how many CPU-seconds and bytes a group consumed - which is how container platforms bill and monitor. The modern unified design is called cgroup v2.
Why it matters: cgroups are what stop one container from starving its neighbours. Without them, a runaway process inside one container could eat all the host's memory or CPU and take everyone down; with them, each container gets a bounded, accountable slice, and noisy neighbours are contained. The honest framing is that cgroups are about resource limits and fairness, NOT about security isolation - that is the namespaces' job. A common mistake is to think 'I limited the cgroup, so the container is safe.' It is bounded, not sandboxed; you need both cgroups (for limits) and namespaces (for isolation), plus more, to make a real container.
Put a process in a cgroup and run: echo 268435456 > memory.max sets that group's memory ceiling to 256 MiB (256 * 1024 * 1024 bytes). If processes in the group allocate past that, the kernel reclaims or OOM-kills within the group - the rest of the host is untouched.
Writing memory.max caps a group's RAM; overruns are handled inside the group, not across the host.
cgroups enforce resource LIMITS and accounting, not security isolation - that is the namespaces' job. 'I set a cgroup limit' does not mean 'the container is sandboxed'; you need namespaces (and more) for that.