Container hanging? How to audit CPU and memory limits
Learn how to diagnose bottlenecks and container freezes by directly inspecting cgroup metrics on the Linux host.
Summary
- The cgroup subsystem directly controls and restricts hardware resources consumed by each process on Linux
- CPU throttling occurs when a container hits its processing ceiling and suffers forced pauses by the OS
- Native virtual filesystem tools reveal actual memory consumption beyond standard monitoring metrics
- Setting limits without monitoring host telemetry leads to false diagnostics of application failures
- Adjusting allocation parameters prevents operational bottlenecks without needing to restart the environment
Why does your container feel sluggish or freeze out of nowhere?
When an application runs inside a Docker container, it shares the exact same operating system kernel of the main computer, known as the host. Often, we notice that the application staggers, takes too long to respond, or seems frozen, while common monitoring tools show plenty of spare capacity. In practice, this means the application might be suffering from an invisible resource squeeze, where the system restricts the pace of work without directly notifying the app. To fully grasp how to prevent these issues, it is worth checking our guide on how to limit resources with cgroups v2 to ensure operational stability.
This mysterious behavior usually happens because Docker uses an internal Linux technology called cgroups, short for control groups. The cgroup acts as a strict doorman that inspects the exact processor, memory, and disk consumption of every running program. If the container tries to use more than agreed upon in the configuration contract, the doorman steps in. Depending on how the environment was set up, it might simply slow down the program or abruptly terminate the process to protect the entire server from catastrophic crashes.
What is CPU throttling and how does it choke your applications?
The computer processor divides time into fractions of milliseconds to handle hundreds of concurrent tasks. When we define a processing limit for a container, the operating system ensures it does not exceed that quota within a specific period. If the container spends its entire time slice before the period ends, the system forces a pause until the next cycle. This mechanism is known as CPU throttling, meaning the choking of processing capacity due to a lack of available quota.
In engineering routines, it is very common to confuse this throttling with a lack of raw hardware capacity. The physical server might have idle cores, but that specific container remains stuck because it hit the ceiling of its own rule. This frequently happens with heavy applications written in languages that use garbage collection, such as Java or Node.js, which experience sudden processing spikes and end up penalized by the restrictive rules imposed by the isolated environment.
How to audit real CPU usage directly from the host filesystem
To find out if your container is suffering from forced pauses, we do not need to install complex monitoring software. The Linux kernel itself stores all these statistics in virtual files organized inside the folder where the cgroup operates. In the modern cgroup v2 system, for example, the file responsible for recording processing stats is called cpu.stat. We can inspect this file directly in the host terminal to extract precise numbers about container behavior.
To perform this audit in practice, you can follow the steps below using your Linux server terminal with administrative privileges.
- Identify the complete unique ID of the running container by running the traditional listing command.
docker ps --no-trunc - Access the directory corresponding to the container inside the operating system resource control tree.
cd /sys/fs/cgroup/docker/<YOUR_CONTAINER_ID> - Read the processing statistics file to check the number of interruptions suffered.
cat cpu.stat
When examining the content returned by this file, pay special attention to two fundamental lines that appear in the listing: nr_throttled and throttled_usec. The first shows how many times the container was braked for exceeding the quota, while the second reveals the total time in microseconds that the application stayed frozen waiting for the next cycle. If these numbers rise rapidly while the application runs, you have mathematical proof that the configured limit is choking the service.
Understanding memory spikes and their hidden impact on the system
While processing suffers temporary pauses, container memory management deals with much stricter and more direct rules. If a program consumes more RAM than allowed, it does not get a breathing pause; in most cases, the operating system applies severe punishment and terminates the process instantly. This event is known as a limit overflow, generating unexpected failures that are often mistaken for application code bugs. To complement your stability analysis and understand the aftermath of these occurrences, also refer to our article on how to audit OOM Killer with dmesg and discover the logs left behind by the system.
To audit actual memory consumption without relying on external dashboards, cgroup v2 provides the memory.current file, which displays precisely how many bytes the container is using at that millisecond. Comparing this value with the maximum limit stipulated in the memory.max file allows predicting failures before the worst happens. If the current value is constantly glued to the ceiling, the application is about to suffer a forced interruption, requiring an urgent infrastructure resize or source code optimization. To explore these architectural concepts further in production, see our related technical analysis on How to Inspect mTLS Traffic in Kubernetes Pods with cURL.
Final considerations to keep containers stable and predictable
Auditing container behavior directly on the Linux host through cgroups transforms how we diagnose performance issues in modern environments. Instead of guessing the root cause based on assumptions, reading kernel metrics directly delivers concrete data on CPU throttling and memory pressure. Thus, we manage to adjust container limits with surgical precision, ensuring services run with high performance, without hardware waste, and free from mysterious daily freezes.