Marcio Cunha

Server out of memory? How to isolate processes with Linux cgroups

Learn how to use Linux cgroups to limit CPU and memory usage of applications, preventing runaway processes from crashing your entire operating system.

Marcio Cunha•5 min
Also available in:PortuguêsEspañol
Summary
  • The Linux kernel cgroups subsystem allows controlling and limiting hardware resources allocated to process groups.
  • Processes without memory limits risk exhausting RAM and triggering the OOM Killer unpredictably.
  • Fine-tuning CPU quotas prevents a runaway task from causing widespread bottlenecks on the machine.
  • Modern tools abstract native complexity, but understanding the sysfs directory structure ensures precise diagnostics.
  • Proper workload isolation guarantees operational stability and prevents downtime in production.

The silent danger of processes without hardware limits

When an application enters an infinite loop or suffers from memory leaks, it begins consuming increasing amounts of machine resources. Within minutes, RAM is exhausted, the system starts swapping to disk, and performance plummets until the machine freezes entirely. In production environments, this destructive behavior can take down multiple critical services hosted on the same server. To prevent a single software from compromising the entire infrastructure, system administrators need to impose rigid hardware usage barriers.

One of the most powerful tools to solve this problem in the Linux kernel is cgroups, short for control groups. It is a native feature that restricts, accounts for, and isolates the usage of resources such as processor, memory, and disk for any set of processes. In practice, it works like a strict traffic officer preventing an application from spending more than its authorized quota. When we combine this isolation with good practices operated in containerized environments, we gain the same load predictability we observe when a container gets stuck on boot and we need to read systemd logs in Docker to understand the failure.

How control groups work inside the Linux kernel

Under the hood, cgroups organizes processes into a hierarchical tree inside the kernel's virtual filesystem, typically located at the sys/fs/cgroup directory. Each folder in this structure represents a group with specific consumption rules. If you move a process into one of these folders, the kernel automatically starts applying the restrictions defined there. This modular architecture ensures that different services run on the same physical machine without aggressively competing for the same processing cycles or free memory blocks.

The modern version of the system, known as cgroups v2, unified resource management so that different subsystems work together much more cohesively. Previously, in the older version, each resource like CPU and memory had separate trees, which made integrated control difficult. Today, with v2, we have a unified model that drastically simplifies auditing and enforcing security policies. This structural evolution directly benefits complex architectures that rely on high resilience, much like when we monitor pod network latency in Kubernetes with eBPF to ensure traffic flows without hidden bottlenecks.

Hands-on: limiting RAM consumption step by step

To get our hands dirty and create a control group dedicated to limiting the memory of a heavy script, we will use the standard cgroups v2 interface. The first step is to create a new directory inside the virtual filesystem structure where the policies will be applied. Open your terminal with administrative privileges and run the command below to create the group named limiter.

sudo mkdir /sys/fs/cgroup/limitador

Next, we need to set the maximum memory ceiling that processes placed in this group can use. Let's establish a strict limit of five hundred megabytes by writing the corresponding value in bytes to the memory control file. The command below configures this restriction immediately in the kernel.

echo '524288000' | sudo tee /sys/fs/cgroup/limitador/memory.max

Finalmente, para colocar um programa em execução sob a tutela desse novo grupo, basta injetar o identificador numérico do processo na lista de tarefas controladas. Com o comando abaixo, o kernel vincula a tarefa ao escopo restrito, garantindo que o consumo excessivo seja contido instantaneamente.

echo $$ | sudo tee /sys/fs/cgroup/limitador/cgroup.procs

Controlando picos de processador para manter a estabilidade

Além da memória, o controle de ciclos de CPU é indispensável para evitar que processos em segundo plano sufoquem o sistema. Através do arquivo cpu.max, conseguimos definir exatamente quanto tempo de processador um grupo pode consumir dentro de uma janela de tempo fixa. Se configurarmos o sistema para permitir no máximo cinquenta mil microssegundos a cada cem mil microssegundos, o grupo terá direito a no máximo meio núcleo de CPU, mesmo que a máquina tenha dezesseis núcleos livres. Essa contenção evita que tarefas de lote causem engasgos perceptíveis nas requisições web síncronas.

O grande ganho operacional dessa abordagem é o determinismo. Em vez de torcer para que a aplicação se comporte bem sob carga extrema, a engenharia impõe limites matemáticos que mantêm a margem de manobra do sistema operacional. Isso reduz drasticamente os chamados de plantão causados por degradação repentina de performance. A mesma disciplina de engenharia que protege nós de processamento locais também se aplica quando automatizamos recuperações em camadas de banco de dados ou quando automatizamos o recovery no PostgreSQL após uma corrupção de dados.

Boas práticas na gestão de recursos com cgroups em produção

Implementar limites de cgroups exige monitoramento contínuo para evitar que o encerramento abrupto de processos cause corrupção de dados. Quando a memória atinge o teto estipulado e o sistema não consegue liberar espaço, o mecanismo de proteção do kernel intervém encerrando a tarefa ofensiva de maneira indesejada. Por isso, configure alertas baseados em métricas de uso antes de aplicar restrições definitivas nos ambientes produtivos. Testar os limites em staging revela o comportamento exato da aplicação sob estresse sem riscos para os usuários finais.

Outro ponto crítico é documentar a hierarquia de grupos criada em cada nó da infraestrutura. Servidores que rodam múltiplos daemons e ferramentas de automação precisam de uma convenção clara de nomes e políticas padronizadas. Manter essa disciplina evita que regras conflitantes sejam aplicadas acidentalmente durante manutenções emergenciais. Com uma arquitetura de isolamento bem planejada, sua operação ganha blindagem contra picos inesperados de tráfego e falhas de software.

Considerações finais sobre o isolamento eficiente de cargas

O domínio do subsistema cgroups transforma a maneira como os engenheiros gerenciam a estabilidade de servidores Linux. Ao compreender que os limites de hardware não são restrições arbitrárias, mas sim ferramentas de design defensivo, criamos ambientes capazes de absorver falhas sem colapsar por completo. A capacidade de isolar falhas de memória e CPU garante que serviços essenciais permaneçam ativos mesmo quando componentes secundários entram em colapso.

Investir tempo na configuração correta desses mecanismos elimina surpresas desagradáveis e eleva o nível de maturidade operacional da equipe. Seja gerenciando servidores dedicados tradicionais ou entendendo os alicerces que sustentam plataformas modernas de containers, o conhecimento de cgroups permanece como uma competência fundamental no arsenal de qualquer profissional de tecnologia focado em resiliência.